This commit is contained in:
Jonatan Rek 2024-08-06 08:31:51 +02:00
parent 2dfb12f23d
commit d0fbb5d5c1
20 changed files with 296 additions and 43 deletions

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers;
use App\Models\MaintenanceHistory;
class TaskController extends BaseController
{
public function index()
{
return view('task.index');
}
}

View File

@ -46,6 +46,7 @@ public function handle(Request $request, Closure $next): Response
$systemRoutes = [ $systemRoutes = [
'Host' => [' fas fa-server', 'host'], 'Host' => [' fas fa-server', 'host'],
'Maintenance' => [' fas fa-calendar', 'maintenance'], 'Maintenance' => [' fas fa-calendar', 'maintenance'],
'Tasks' => [' fas fa-calendar', 'tasks'],
]; ];
foreach ($systemRoutes as $title => $route_data) { foreach ($systemRoutes as $title => $route_data) {

View File

@ -37,15 +37,22 @@ public function handle(): void
} }
$cron = new CronExpression($maintenance->schedule); $cron = new CronExpression($maintenance->schedule);
if (!$cron->isDue('now')) { $maintenancePlanned = $maintenance->history()->create([
dd($cron->getNextRunDate());
return;
}
$maintenance->history()->create([
'start_at' => $cron->getNextRunDate(null, 2) 'start_at' => $cron->getNextRunDate(null, 2)
]); ]);
$maintenancePlanned->refresh();
$tasks = $maintenancePlanned->tasks;
if(!empty($tasks)){
dd($tasks);
foreach ($tasks as $key => $task) {
$maintenancePlanned->tasks()->create([
'host_id' => $task->host_id,
]);
}
}
}
die(); die();
} }
} }
}

View File

@ -5,6 +5,8 @@
use App\Models\Host; use App\Models\Host;
use Livewire\Component; use Livewire\Component;
use App\Models\Maintenance; use App\Models\Maintenance;
use App\Models\MaintenanceTask;
use Illuminate\Console\View\Components\Task;
class Form extends Component class Form extends Component
{ {
@ -18,6 +20,8 @@ class Form extends Component
public $hosts = []; public $hosts = [];
public $hosts_available = []; public $hosts_available = [];
public $hosts_tasks = [];
public $hosts_tasks_available = [];
protected function rules() protected function rules()
{ {
@ -31,6 +35,8 @@ protected function rules()
public function mount($model = null) public function mount($model = null)
{ {
$this->hosts_available = Host::all()->pluck('hostname', 'id')->toArray(); $this->hosts_available = Host::all()->pluck('hostname', 'id')->toArray();
$this->hosts_tasks_available = MaintenanceTask::all()->pluck('name', 'id')->toArray();
if (!empty($model)) { if (!empty($model)) {
$maintenance = Maintenance::find($model); $maintenance = Maintenance::find($model);
@ -39,7 +45,11 @@ public function mount($model = null)
$this->name = $maintenance->name; $this->name = $maintenance->name;
$this->description = $maintenance->description; $this->description = $maintenance->description;
$this->schedule = $maintenance->schedule; $this->schedule = $maintenance->schedule;
$this->hosts = $maintenance->hosts()->pluck('hosts.id')->toArray(); $this->hosts = $maintenance->hosts()->pluck('hosts.id')->toArray();
foreach ($maintenance->tasks as $task) {
$this->hosts_tasks_available[$task->host_id][] = $task->id;
}
$this->action = 'update'; $this->action = 'update';
} }
@ -68,6 +78,14 @@ public function update()
foreach ($hosts as $key => $host) { foreach ($hosts as $key => $host) {
$maintenance->hosts()->attach($host); $maintenance->hosts()->attach($host);
} }
$maintenance->refresh();
foreach ($maintenance->hosts as $host) {
foreach ($this->hosts_tasks[$host->id] as $task_id => $host_task_name) {
$host->tasks()->create([
'task_id' => $task_id
]);
}
}
} }
$this->dispatch('closeModal'); $this->dispatch('closeModal');

View File

@ -0,0 +1,54 @@
<?php
namespace App\Livewire\MaintenanceTask;
use App\Models\MaintenanceTask;
use SteelAnts\DataTable\Livewire\DataTableComponent;
use Illuminate\Database\Eloquent\Builder;
class DataTable extends DataTableComponent
{
public $listeners = [
'maintenancetaskAdded' => '$refresh',
'closeModal' => '$refresh',
];
public function query(): Builder
{
return MaintenanceTask::query();
}
public function headers(): array
{
return [
'name' => 'name',
'description' => 'description',
];
}
public function remove($maintenancetask_id){
MaintenanceTask::find($maintenancetask_id)->delete();
}
public function actions($item)
{
return [
[
'type' => "livewire",
'action' => "edit",
'text' => "edit",
'parameters' => $item['id']
],
[
'type' => "livewire",
'action' => "remove",
'text' => "remove",
'parameters' => $item['id']
]
];
}
public function edit($maintenancetask_id)
{
$this->dispatch('openModal', 'maintenance-task.form', __('boilerplate::maintenance-task.edit'), ['model' => $maintenancetask_id]);
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace App\Livewire\MaintenanceTask;
use Livewire\Component;
use App\Models\MaintenanceTask;
class Form extends Component
{
public $model;
public string $maintenance_id;
public string $name;
public string $description = "";
public $action = 'store';
protected function rules()
{
return [
'maintenance_id' => 'required',
'name' => 'required',
'description' => 'required',
];
}
public function mount ($model = null){
if (!empty($model)) {
$maintenanceTask = MaintenanceTask::find($model);
$this->model = $model;
$this->maintenance_id = $maintenanceTask->maintenance_id;
$this->name = $maintenanceTask->name;
$this->description = $maintenanceTask->description;
$this->action = 'update';
}
}
public function store()
{
$validatedData = $this->validate();
MaintenanceTask::create($validatedData);
$this->dispatch('closeModal');
}
public function update()
{
$validatedData = $this->validate();
$maintenanceTask = MaintenanceTask::find($this->model);
if (!empty($maintenanceTask)) {
$maintenanceTask->update($validatedData);
}
$this->dispatch('closeModal');
}
public function render()
{
return view('livewire.maintenance-task.form');
}
}

View File

@ -12,4 +12,9 @@ class Host extends Model
protected $fillable = [ protected $fillable = [
'hostname', 'hostname',
]; ];
public function tasks()
{
return $this->hasMany(MaintenanceTask::class,);
}
} }

View File

@ -24,4 +24,9 @@ public function hosts()
{ {
return $this->belongsToMany(Host::class, "maintenance_host", "maintenance_id", "host_id" ); return $this->belongsToMany(Host::class, "maintenance_host", "maintenance_id", "host_id" );
} }
public function tasks()
{
return $this->hasMany(MaintenanceTask::class,);
}
} }

View File

@ -8,4 +8,14 @@
class MaintenanceHostHistory extends Model class MaintenanceHostHistory extends Model
{ {
use HasFactory; use HasFactory;
public function hosts()
{
return $this->belongsToMany(MaintenanceHostHistory::class);
}
public function tasks()
{
return $this->hasMany(MaintenanceTaskHistory::class);
}
} }

View File

@ -8,4 +8,11 @@
class MaintenanceTask extends Model class MaintenanceTask extends Model
{ {
use HasFactory; use HasFactory;
protected $fillable = [
'maintenance_id',
'host_id',
'name',
'description',
];
} }

View File

@ -8,4 +8,9 @@
class MaintenanceTaskHistory extends Model class MaintenanceTaskHistory extends Model
{ {
use HasFactory; use HasFactory;
public function task()
{
return $this->BelongsTo(MaintenanceTask::class);
}
} }

11
app/Models/Task.php Normal file
View File

@ -0,0 +1,11 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
use HasFactory;
}

58
composer.lock generated
View File

@ -3250,16 +3250,16 @@
}, },
{ {
"name": "steelants/datatable", "name": "steelants/datatable",
"version": "2.2.5", "version": "2.2.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/steelants/Livewire-DataTable.git", "url": "https://github.com/steelants/Livewire-DataTable.git",
"reference": "398cef188e063ef17e11905b010210db2d71d58f" "reference": "69f5a3e2abbfa861fe5a3bfb7b4e16603a2582f3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/steelants/Livewire-DataTable/zipball/398cef188e063ef17e11905b010210db2d71d58f", "url": "https://api.github.com/repos/steelants/Livewire-DataTable/zipball/69f5a3e2abbfa861fe5a3bfb7b4e16603a2582f3",
"reference": "398cef188e063ef17e11905b010210db2d71d58f", "reference": "69f5a3e2abbfa861fe5a3bfb7b4e16603a2582f3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3291,9 +3291,9 @@
"description": "Simple Datatable class based on Laravel and livewire", "description": "Simple Datatable class based on Laravel and livewire",
"support": { "support": {
"issues": "https://github.com/steelants/Livewire-DataTable/issues", "issues": "https://github.com/steelants/Livewire-DataTable/issues",
"source": "https://github.com/steelants/Livewire-DataTable/tree/2.2.5" "source": "https://github.com/steelants/Livewire-DataTable/tree/2.2.6"
}, },
"time": "2024-07-23T15:07:07+00:00" "time": "2024-07-31T15:08:12+00:00"
}, },
{ {
"name": "steelants/form", "name": "steelants/form",
@ -6338,16 +6338,16 @@
}, },
{ {
"name": "laravel/pint", "name": "laravel/pint",
"version": "v1.17.0", "version": "v1.17.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/pint.git", "url": "https://github.com/laravel/pint.git",
"reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5" "reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", "url": "https://api.github.com/repos/laravel/pint/zipball/b5b6f716db298671c1dfea5b1082ec2c0ae7064f",
"reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", "reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6400,7 +6400,7 @@
"issues": "https://github.com/laravel/pint/issues", "issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint" "source": "https://github.com/laravel/pint"
}, },
"time": "2024-07-23T16:40:20+00:00" "time": "2024-08-01T09:06:33+00:00"
}, },
{ {
"name": "laravel/sail", "name": "laravel/sail",
@ -6678,23 +6678,23 @@
}, },
{ {
"name": "nunomaduro/collision", "name": "nunomaduro/collision",
"version": "v8.3.0", "version": "v8.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nunomaduro/collision.git", "url": "https://github.com/nunomaduro/collision.git",
"reference": "b49f5b2891ce52726adfd162841c69d4e4c84229" "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/b49f5b2891ce52726adfd162841c69d4e4c84229", "url": "https://api.github.com/repos/nunomaduro/collision/zipball/e7d1aa8ed753f63fa816932bbc89678238843b4a",
"reference": "b49f5b2891ce52726adfd162841c69d4e4c84229", "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"filp/whoops": "^2.15.4", "filp/whoops": "^2.15.4",
"nunomaduro/termwind": "^2.0.1", "nunomaduro/termwind": "^2.0.1",
"php": "^8.2.0", "php": "^8.2.0",
"symfony/console": "^7.1.2" "symfony/console": "^7.1.3"
}, },
"conflict": { "conflict": {
"laravel/framework": "<11.0.0 || >=12.0.0", "laravel/framework": "<11.0.0 || >=12.0.0",
@ -6702,13 +6702,13 @@
}, },
"require-dev": { "require-dev": {
"larastan/larastan": "^2.9.8", "larastan/larastan": "^2.9.8",
"laravel/framework": "^11.16.0", "laravel/framework": "^11.19.0",
"laravel/pint": "^1.16.2", "laravel/pint": "^1.17.1",
"laravel/sail": "^1.30.2", "laravel/sail": "^1.31.0",
"laravel/sanctum": "^4.0.2", "laravel/sanctum": "^4.0.2",
"laravel/tinker": "^2.9.0", "laravel/tinker": "^2.9.0",
"orchestra/testbench-core": "^9.2.1", "orchestra/testbench-core": "^9.2.3",
"pestphp/pest": "^2.34.9 || ^3.0.0", "pestphp/pest": "^2.35.0 || ^3.0.0",
"sebastian/environment": "^6.1.0 || ^7.0.0" "sebastian/environment": "^6.1.0 || ^7.0.0"
}, },
"type": "library", "type": "library",
@ -6771,7 +6771,7 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2024-07-16T22:41:01+00:00" "time": "2024-08-03T15:32:23+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@ -7216,16 +7216,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "11.2.9", "version": "11.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "c197bbaaca360efda351369bf1fd9cc1ca6bcbf7" "reference": "a8dce73a8938dfec7ac0daa91bdbcaae7d7188a3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c197bbaaca360efda351369bf1fd9cc1ca6bcbf7", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a8dce73a8938dfec7ac0daa91bdbcaae7d7188a3",
"reference": "c197bbaaca360efda351369bf1fd9cc1ca6bcbf7", "reference": "a8dce73a8938dfec7ac0daa91bdbcaae7d7188a3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7264,7 +7264,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "11.2-dev" "dev-main": "11.3-dev"
} }
}, },
"autoload": { "autoload": {
@ -7296,7 +7296,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.9" "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.0"
}, },
"funding": [ "funding": [
{ {
@ -7312,7 +7312,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-30T11:09:23+00:00" "time": "2024-08-02T03:56:43+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",

View File

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tasks');
}
};

View File

@ -1,6 +1,8 @@
<?php <?php
use App\Models\Host;
use App\Models\Maintenance; use App\Models\Maintenance;
use App\Models\Task;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
@ -15,8 +17,7 @@ public function up(): void
Schema::create('maintenance_tasks', function (Blueprint $table) { Schema::create('maintenance_tasks', function (Blueprint $table) {
$table->id(); $table->id();
$table->foreignIdFor(Maintenance::class); $table->foreignIdFor(Maintenance::class);
$table->string('name'); $table->foreignIdFor(Task::class);
$table->text('description');
$table->timestamps(); $table->timestamps();
}); });
} }

View File

@ -19,8 +19,8 @@ public function up(): void
$table->foreignIdFor(MaintenanceTask::class); $table->foreignIdFor(MaintenanceTask::class);
$table->foreignIdFor(MaintenanceHistory::class); $table->foreignIdFor(MaintenanceHistory::class);
$table->foreignIdFor(Host::class); $table->foreignIdFor(Host::class);
$table->string('status'); $table->string('status')->default(1);
$table->datetime('finished_at'); $table->datetime('finished_at')->nullable();
$table->timestamps(); $table->timestamps();
}); });
} }

View File

@ -0,0 +1,8 @@
<div>
<x-form::form wire:submit.prevent="{{$action}}">
<x-form::input group-class="mb-3" type="text" wire:model="maintenance_id" id="maintenance_id" label="maintenance_id"/>
<x-form::input group-class="mb-3" type="text" wire:model="name" id="name" label="name"/>
<x-form::quill group-class="mb-3" type="text" wire:model="description" id="description" label="description" />
<x-form::button class="btn-primary" type="submit">Create</x-form::button>
</x-form::form>
</div>

View File

@ -3,8 +3,13 @@
<x-form::input group-class="mb-3" type="text" wire:model="name" id="name" label="name" /> <x-form::input group-class="mb-3" type="text" wire:model="name" id="name" label="name" />
<x-form::quill group-class="mb-3" type="text" wire:model="description" id="description" label="description" /> <x-form::quill group-class="mb-3" type="text" wire:model="description" id="description" label="description" />
<x-form::input group-class="mb-3" type="text" wire:model="schedule" id="schedule" label="schedule" /> <x-form::input group-class="mb-3" type="text" wire:model="schedule" id="schedule" label="schedule" />
<x-form::select group-class="mb-3" wire:model="hosts" label="Livewire Select" :options="$hosts_available" placeholder="Select value..." multiple /> <x-form::select group-class="mb-3" wire:model.live="hosts" label="Livewire Select" :options="$hosts_available" placeholder="Select value..." multiple />
@foreach($hosts as $host_id)
<x-form::select group-class="mb-3" wire:model="hosts_tasks.{{ $host_id }}" label="Select Tasks for Host {{ $hosts_available[$host_id] }}" :options="$hosts_tasks_available" placeholder="Select value..." multiple />
@endforeach
<x-form::button class="btn-primary" type="submit">Create</x-form::button> <x-form::button class="btn-primary" type="submit">Create</x-form::button>
@dump($hosts) @dump($hosts_tasks)
</x-form::form> </x-form::form>
</div> </div>

View File

@ -0,0 +1,13 @@
<x-layout-app>
<div class="container-xl">
<div class="page-header">
<h1>{{ __('boilerplate::maintenance-task.title') }}</h1>
<button class="btn btn-primary" onclick="Livewire.dispatch('openModal', {livewireComponents: 'maintenance-task.form', title: '{{ __('boilerplate::maintenance-task.create') }}'})">
<i class="me-2 fas fa-plus"></i><span>{{ __('boilerplate::ui.add') }}</span>
</button>
</div>
@livewire('maintenance-task.data-table', [], key('data-table'))
</div>
</x-layout-app>

View File

@ -14,6 +14,7 @@
Route::get('/host', [App\Http\Controllers\HostController::class, 'index'])->name('host'); Route::get('/host', [App\Http\Controllers\HostController::class, 'index'])->name('host');
Route::get('/maintenance', [App\Http\Controllers\MaintenanceController::class, 'index'])->name('maintenance'); Route::get('/maintenance', [App\Http\Controllers\MaintenanceController::class, 'index'])->name('maintenance');
Route::get('/tasks', [App\Http\Controllers\TaskController::class, 'index'])->name('tasks');
Route::prefix('profile')->name('profile.')->middleware(['auth'])->group(function () { Route::prefix('profile')->name('profile.')->middleware(['auth'])->group(function () {