laravel reverb working

This commit is contained in:
guillaume91 2024-05-28 16:38:27 +02:00
parent 336bafd6f4
commit faa2b5a782
19 changed files with 197 additions and 56 deletions

View file

@ -1,30 +0,0 @@
<?php
namespace App\Events;
use App\Models\ProjectDownload;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class DownloadStatusPending implements ShouldBroadcast
{
public ProjectDownload $projectDownload;
/**
* Create a new event instance.
*/
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new PrivateChannel('channel-name'),
];
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace App\Events;
use App\Models\ProjectDownload;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class ProjectDownloadStatus implements ShouldBroadcastNow
{
use SerializesModels;
public ProjectDownload $projectDownload;
/**
* Create a new event instance.
*/
public function __construct($projectDownload)
{
$this->projectDownload = $projectDownload;
}
/**
* Get the channels the event should broadcast on.
*
*/
public function broadcastOn(): array
{
return [new PrivateChannel('download.'.$this->projectDownload->id)];
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace App\Events;
use App\Models\ProjectMosaic;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class ProjectMosaicStatus implements ShouldBroadcastNow
{
use SerializesModels;
public ProjectMosaic $projectMosaic;
/**
* Create a new event instance.
*/
public function __construct(ProjectMosaic $projectMosaic)
{
//
$this->projectMosaic = $projectMosaic;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [new PrivateChannel('mosaic.'.$this->projectMosaic->id)];
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace App\Events;
use App\Models\ProjectReport;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class ProjectReportStatus implements ShouldBroadcast
{
use SerializesModels;
public ProjectReport $projectReport;
/**
* Create a new event instance.
*/
public function __construct(ProjectReport $projectReport)
{
//
$this->projectReport = $projectReport;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, Channel>
*/
public function broadcastOn(): array
{
return [new PrivateChannel('report.'.$this->projectReport->id)];
}
}

View file

@ -5,10 +5,16 @@
use App\Livewire\Forms\MailingForm; use App\Livewire\Forms\MailingForm;
use App\Models\ProjectReport; use App\Models\ProjectReport;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Livewire\Attributes\Reactive;
use Livewire\Component; use Livewire\Component;
class ReportRow extends Component class ReportRow extends Component
{ {
protected $listeners = [
// 'Badge:refresh' => '$refresh',
];
#[Reactive]
public ProjectReport $report; public ProjectReport $report;
public MailingForm $mailingForm; public MailingForm $mailingForm;

View file

@ -21,6 +21,10 @@ class Download extends Component
public $search = ''; public $search = '';
public $listeners = [
'Badge:refresh' => '$refresh',
];
public function mount(Project $project) public function mount(Project $project)

View file

@ -20,6 +20,9 @@ class Mosaic extends Component
public $showCreateModal = false; public $showCreateModal = false;
public $search = ""; public $search = "";
protected $listeners = [
'Badge:refresh' => '$refresh',
];
public function mount(Project $project) public function mount(Project $project)
{ {

View file

@ -20,7 +20,9 @@ class Report extends Component
public $showReportModal = false; public $showReportModal = false;
public $listeners = ['refresh' => '$refresh']; public $listeners = [
'Badge:refresh' => '$refresh'
];
public function openCreateReportModal() public function openCreateReportModal()
{ {
@ -97,11 +99,13 @@ public function render()
{ {
$query = Project::find($this->project->id) $query = Project::find($this->project->id)
->reports() ->reports()
->with('project')
->orderBy('year', 'desc') ->orderBy('year', 'desc')
->orderBy('week', 'desc'); ->orderBy('week', 'desc');
$query = $this->applySearch($query); $query = $this->applySearch($query);
$reports = $query->paginate(10, pageName: 'reportPage'); $reports = $query->paginate(10, pageName: 'reportPage');
return view('livewire.projects.tabs.report') return view('livewire.projects.tabs.report')
->with(compact('reports')); ->with(compact('reports'));
} }

View file

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Events\ProjectDownloadStatus;
use App\Traits\HasStatus; use App\Traits\HasStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -15,10 +16,19 @@ class ProjectDownload extends Model
protected $fillable = [ protected $fillable = [
'name', 'name',
'path', 'path',
'status'
]; ];
public function project(): \Illuminate\Database\Eloquent\Relations\BelongsTo public function project(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{ {
return $this->belongsTo(Project::class); return $this->belongsTo(Project::class);
} }
protected static function booted(): void
{
parent::booted();
static::updated(function (ProjectDownload $projectDownload) {
event(new ProjectDownloadStatus($projectDownload));
});
}
} }

View file

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Events\ProjectMosaicStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -15,6 +16,7 @@ class ProjectMosaic extends Model
'path', 'path',
'week', 'week',
'year', 'year',
'status'
]; ];
public function project() public function project()
@ -22,4 +24,12 @@ public function project()
return $this->belongsTo(Project::class); return $this->belongsTo(Project::class);
} }
protected static function booted(): void
{
parent::booted();
static::updated(function (ProjectMosaic $projectMosaic) {
event(new ProjectMosaicStatus($projectMosaic));
});
}
} }

View file

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Events\ProjectReportStatus;
use App\Jobs\ProjectDownloadTiffJob; use App\Jobs\ProjectDownloadTiffJob;
use App\Jobs\ProjectMosiacGeneratorJob; use App\Jobs\ProjectMosiacGeneratorJob;
use App\Traits\HasStatus; use App\Traits\HasStatus;
@ -14,7 +15,7 @@
class ProjectReport extends Model class ProjectReport extends Model
{ {
use HasStatus; use HasStatus;
protected $fillable = ['name', 'path', 'week', 'year']; protected $fillable = ['name', 'path', 'week', 'year','status'];
@ -74,5 +75,13 @@ public function deleteMe()
$this->delete(); $this->delete();
} }
protected static function booted(): void
{
parent::booted();
static::updated(function (ProjectReport $projectReport) {
event(new ProjectReportStatus($projectReport));
});
}
} }

View file

@ -13,9 +13,11 @@ class Badge extends Component
*/ */
public array $colorClasses; public array $colorClasses;
public Status $status; public Status $status;
public int $id;
public function __construct($status = null) public function __construct($status = null, $id = 0)
{ {
$this->id ??= $id ;
$this->status = Status::tryFrom($status) ?? Status::Success; $this->status = Status::tryFrom($status) ?? Status::Success;
$this->colorClasses = match($this->status) { $this->colorClasses = match($this->status) {
Status::Success => ['bg' => 'bg-green-100', 'text' => 'text-green-700'], Status::Success => ['bg' => 'bg-green-100', 'text' => 'text-green-700'],

View file

@ -1,17 +1,20 @@
import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm'; import {Livewire, Alpine} from '../../vendor/livewire/livewire/dist/livewire.esm';
// import Intersect from "@alpinejs/intersect"; // import Intersect from "@alpinejs/intersect";
import focus from "@alpinejs/focus"; import focus from "@alpinejs/focus";
// import Clipboard from "@ryangjchandler/alpine-clipboard"; // import Clipboard from "@ryangjchandler/alpine-clipboard";
// import collapse from "@alpinejs/collapse"; // import collapse from "@alpinejs/collapse";
import ui from "@alpinejs/ui"; import ui from "@alpinejs/ui";
Alpine.plugin(ui)
Alpine.plugin(focus) Alpine.plugin(ui);
Alpine.plugin(focus);
// Alpine.plugin(Clipboard); // Alpine.plugin(Clipboard);
// Alpine.plugin(Intersect); // Alpine.plugin(Intersect);
// Alpine.plugin(collapse); // Alpine.plugin(collapse);
import htabs from './history-tabs'; import htabs from './history-tabs';
htabs(Alpine)
window.Alpine = Alpine htabs(Alpine);
window.Alpine = Alpine;
Alpine.start();
Livewire.start(); Livewire.start();

View file

@ -2,3 +2,4 @@ import './bootstrap';
import('./alpine'); import('./alpine');
import flatpckr from 'flatpickr'; import flatpckr from 'flatpickr';
window.flatpckr = flatpckr; window.flatpckr = flatpckr;

View file

@ -1,3 +1,11 @@
<span {{ $attributes }} class="inline-flex items-center rounded-md {{ $colorClasses['bg'] }} px-1.5 py-0.5 text-xs font-medium {{ $colorClasses['text'] }}"> <span {{ $attributes }} class="inline-flex items-center rounded-md {{ $colorClasses['bg'] }} px-1.5 py-0.5 text-xs font-medium {{ $colorClasses['text'] }}"
@if($attributes['type'])
x-init="Echo.private(`{{$attributes['type']}}.@js($id)`).listen('Project{{ucfirst($attributes['type'])}}Status', (e) => {
console.log(e.project{{ucfirst($attributes['type'])}}.status);
$wire.dispatch('Badge:refresh');
});"
x-destroy="Echo.leaveChannel(`{{$attributes['type']}}.@js($id)`);"
@endif
>
{{ $status }} {{ $status }}
</span> </span>

View file

@ -5,11 +5,12 @@
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">{{ $report->name }}</td> <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">{{ $report->name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"> <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
@if($report->status == \App\Enums\Status::Pending) {{-- @if($report->status == \App\Enums\Status::Pending)--}}
<x-badge status="pending" wire:poll.1s=""></x-badge> {{-- <x-badge status="pending" wire:poll.1s=""></x-badge>--}}
@else {{-- @else--}}
<x-badge :status="$report->status"></x-badge> {{-- <x-badge :status="$report->status"></x-badge>--}}
@endif {{-- @endif--}}
<x-badge :status="$report->status" :id="$report->id" type="report"></x-badge>
</td> </td>
<td class="py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8 flex justify-end"> <td class="py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8 flex justify-end">
<x-menu> <x-menu>

View file

@ -1,8 +1,8 @@
<div <div
{{-- @if($project->hasPendingDownload())--}} {{-- @if($project->hasPendingDownload())--}}
{{-- wire:poll.1s=""--}} {{-- wire:poll.1s=""--}}
{{-- @endif--}} {{-- @endif--}}
{{-- TODO Put Back the poll but to the list of downloads only--}} {{-- TODO Put Back the poll but to the list of downloads only--}}
class="m-2" class="m-2"
> >
<div class="sm:flex sm:flex-col"> <div class="sm:flex sm:flex-col">
@ -50,8 +50,9 @@ class="px-3 py-3.5 text-right pr-4 sm:pr-8 lg:pr-8 text-sm font-semibold text-gr
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"> <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
{{ $download->path }} {{ $download->path }}
</td> </td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8"> <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8"
<x-badge :status="$download->status"></x-badge> >
<x-badge :status="$download->status" :id="$download->id" type="download"></x-badge>
</td> </td>
</tr> </tr>
@endforeach @endforeach

View file

@ -1,8 +1,4 @@
<div <div>
@if($project->hasPendingMosaic())
wire:poll.1s=""
@endif
>
<div class="px-4 "> <div class="px-4 ">
<div class="sm:flex sm:flex-col sm:items-center"> <div class="sm:flex sm:flex-col sm:items-center">
<div class="flex justify-between w-full my-4"> <div class="flex justify-between w-full my-4">
@ -49,7 +45,7 @@ class="px-3 py-3.5 text-right text-sm font-semibold text-gray-900 sm:pr-8 lg:pr-
{{ $mosaic->year }}-{{ $mosaic->week}} {{ $mosaic->year }}-{{ $mosaic->week}}
</td> </td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8"> <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
<x-badge :status="$mosaic->status"></x-badge> <x-badge :status="$mosaic->status" :id="$mosaic->id" type="mosaic"></x-badge>
</td> </td>
</tr> </tr>
@endforeach @endforeach

View file

@ -16,3 +16,14 @@
Broadcast::channel('App.Models.User.{id}', function ($user, $id) { Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id; return (int) $user->id === (int) $id;
}); });
Broadcast::channel('download.{downloadId}', function ($user, $downloadId) {
return true;
});
Broadcast::channel('mosaic.{mosaicId}', function ($user, $mosaicId) {
return true;
});
Broadcast::channel('report.{reportId}', function ($user, $reportId) {
return true;
});