[done] badge uses websocket (Laravel Reverb)
This commit is contained in:
parent
f44329b508
commit
acd8d0ea32
40
laravel_app/app/Events/ProjectMailingStatus.php
Normal file
40
laravel_app/app/Events/ProjectMailingStatus.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\ProjectMailing;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ProjectMailingStatus implements ShouldBroadcast
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public ProjectMailing $projectMailing;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct(ProjectMailing $projectMailing)
|
||||
{
|
||||
//
|
||||
$this->projectMailing = $projectMailing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('mailing.'.$this->projectMailing->id),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -7,25 +7,39 @@
|
|||
|
||||
class Badge extends Component
|
||||
{
|
||||
public array $colorClasses;
|
||||
public $status;
|
||||
public $type;
|
||||
public string $type;
|
||||
public int $id;
|
||||
public $listeners = [
|
||||
'Badge:refresh' => '$refresh',
|
||||
// 'Badge:refresh' => '$refresh',
|
||||
];
|
||||
|
||||
public function mount(string $status = null, $id = 0,$type = null)
|
||||
public function mount(string $status = null, $id = 0, $type = null)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->id ??= $id ;
|
||||
$this->id ??= $id;
|
||||
$this->status = Status::tryFrom($status) ?? Status::Success;
|
||||
$this->colorClasses = match($this->status) {
|
||||
Status::Success => ['bg' => 'bg-green-100', 'text' => 'text-green-700'],
|
||||
Status::Failed => ['bg' => 'bg-red-100', 'text' => 'text-red-700'],
|
||||
Status::Pending => ['bg' => 'bg-gray-100', 'text' => 'text-gray-600'],
|
||||
}
|
||||
|
||||
public function getColorClasses(): string
|
||||
{
|
||||
return match ($this->status) {
|
||||
Status::Success => 'bg-green-100 text-green-700',
|
||||
Status::Failed => 'bg-red-100 text-red-700',
|
||||
Status::Pending => 'bg-gray-100 text-gray-600',
|
||||
};
|
||||
}
|
||||
|
||||
public function setStatus(string $status): void
|
||||
{
|
||||
$this->status = Status::tryFrom($status) ?? Status::Success;
|
||||
}
|
||||
|
||||
public function refreshPage()
|
||||
{
|
||||
$this->dispatch('Badge:refresh');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.components.badge');
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
class ReportRow extends Component
|
||||
{
|
||||
protected $listeners = [
|
||||
// 'Badge:refresh' => '$refresh',
|
||||
'Badge:refresh' => '$refresh',
|
||||
];
|
||||
|
||||
#[Reactive]
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ class Mailings extends Component
|
|||
public $search = '';
|
||||
|
||||
public $active_mailing = null;
|
||||
|
||||
protected $listeners = [
|
||||
'Badge:refresh' => '$refresh',
|
||||
];
|
||||
public function mount(Project $project)
|
||||
{
|
||||
$this->project = $project;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class Report extends Component
|
|||
public $showReportModal = false;
|
||||
|
||||
public $listeners = [
|
||||
'Badge:refresh' => '$refresh'
|
||||
'Badge:refresh' => '$refresh',
|
||||
];
|
||||
|
||||
public function openCreateReportModal()
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ public function allMosaicsPresent(Carbon $endDate): bool
|
|||
$mosaicsNotPresentInFilesystem = $this->getMosaicFilenameListByEndDate($endDate)
|
||||
->filter(function ($filename) {
|
||||
return !$this->getMosaicList()->contains(function ($mosaicFilename) use ($filename) {
|
||||
// TODO check the value of the week leading 0
|
||||
return Str::endsWith($mosaicFilename, substr($filename, -16));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\ProjectMailingStatus;
|
||||
use App\Traits\HasStatus;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Str;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ProjectMailing extends Model
|
||||
{
|
||||
|
|
@ -19,6 +19,7 @@ class ProjectMailing extends Model
|
|||
protected $fillable = [
|
||||
'subject',
|
||||
'message',
|
||||
'status'
|
||||
];
|
||||
|
||||
|
||||
|
|
@ -63,4 +64,12 @@ protected function subject(): Attribute
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
parent::booted();
|
||||
static::updated(function (ProjectMailing $projectMailing) {
|
||||
event(new ProjectMailingStatus($projectMailing));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public function __construct($projectId)
|
|||
public function passes($attribute, $value)
|
||||
{
|
||||
try {
|
||||
/** @var Project $project */
|
||||
$project = Project::find($this->projectId);
|
||||
|
||||
if (!$project) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class Badge extends Component
|
|||
public Status $status;
|
||||
public int $id;
|
||||
|
||||
|
||||
public function __construct($status = null, $id = 0)
|
||||
{
|
||||
$this->id ??= $id ;
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@
|
|||
"src": "node_modules/@fortawesome/fontawesome-free/webfonts/fa-v4compatibility.woff2"
|
||||
},
|
||||
"resources/css/app.css": {
|
||||
"file": "assets/app-4a859431.css",
|
||||
"file": "assets/app-93dd061f.css",
|
||||
"isEntry": true,
|
||||
"src": "resources/css/app.css"
|
||||
},
|
||||
"resources/js/alpine.js": {
|
||||
"file": "assets/alpine-d6afa966.js",
|
||||
"file": "assets/alpine-e0ba2549.js",
|
||||
"isDynamicEntry": true,
|
||||
"src": "resources/js/alpine.js"
|
||||
},
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
"dynamicImports": [
|
||||
"resources/js/alpine.js"
|
||||
],
|
||||
"file": "assets/app-f5ffacbb.js",
|
||||
"file": "assets/app-eb81fffd.js",
|
||||
"isEntry": true,
|
||||
"src": "resources/js/app.js"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,5 +16,4 @@ htabs(Alpine);
|
|||
|
||||
|
||||
window.Alpine = Alpine;
|
||||
Alpine.start();
|
||||
Livewire.start();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<span {{ $attributes }} class="inline-flex items-center rounded-md {{ $colorClasses['bg'] }} px-1.5 py-0.5 text-xs font-medium {{ $colorClasses['text'] }}"
|
||||
<span 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);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<span class="inline-flex items-center rounded-md {{ $colorClasses['bg'] }} px-1.5 py-0.5 text-xs font-medium {{ $colorClasses['text'] }}"
|
||||
<span class="inline-flex items-center rounded-md {{ $this->getColorClasses() }} px-1.5 py-0.5 text-xs font-medium"
|
||||
@if($this->type)
|
||||
x-init="Echo.private(`{{$this->type}}.@js($id)`).listen('Project{{ucfirst($this->type)}}Status', (e) => {
|
||||
x-init="Echo.private(`{{$this->type}}.@js($this->id)`).listen('Project{{ucfirst($this->type)}}Status', (e) => {
|
||||
console.log(e.project{{ucfirst($this->type)}}.status);
|
||||
$wire.dispatch('Badge:refresh');
|
||||
if(e.project{{ucfirst($this->type)}}.status){
|
||||
$wire.setStatus(e.project{{ucfirst($this->type)}}.status);
|
||||
$wire.refreshPage();
|
||||
}
|
||||
});"
|
||||
x-destroy="Echo.leaveChannel(`{{$this->type}}.@js($id)`);"
|
||||
x-destroy="Echo.leaveChannel(`{{$this->type}}.@js($this->id)`);"
|
||||
@endif
|
||||
>
|
||||
{{ $status }}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
{{-- @else--}}
|
||||
{{-- <x-badge :status="$report->status"></x-badge>--}}
|
||||
{{-- @endif--}}
|
||||
<x-badge :status="$report->status" :id="$report->id" type="report"></x-badge>
|
||||
<livewire:components.badge :status="$report->status" :id="$report->id" :type="'report'" wire:key="{{$report->id}}"></livewire:components.badge>
|
||||
</td>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
<div
|
||||
{{-- @if($project->hasPendingDownload())--}}
|
||||
{{-- wire:poll.1s=""--}}
|
||||
{{-- @endif--}}
|
||||
{{-- TODO Put Back the poll but to the list of downloads only--}}
|
||||
class="m-2"
|
||||
>
|
||||
<div class="m-2">
|
||||
<div class="sm:flex sm:flex-col">
|
||||
<div class="flex flex-col md:flex-row md:justify-between items-center w-full my-4">
|
||||
<h1 class="text-base font-semibold leading-6 text-gray-900">Downloads</h1>
|
||||
|
|
@ -52,7 +46,7 @@ class="px-3 py-3.5 text-right pr-4 sm:pr-8 lg:pr-8 text-sm font-semibold text-gr
|
|||
</td>
|
||||
<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" :id="$download->id" type="download"></x-badge>
|
||||
<livewire:components.badge :status="$download->status" :id="$download->id" type="download" wire:key="{{$download->id}}"></livewire:components.badge>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">@lang('Attachm
|
|||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">{{ $mail->id }}</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ $mail->subject }}</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<x-badge :status="$mail->status"></x-badge>
|
||||
<livewire:components.badge :status="$mail->status" :id="$mail->id" type="mailing" wire:key="{{$mail->id}}"></livewire:components.badge>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ $mail->recipients()->count() }}</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ $mail->attachments()->pluck('name')->join( ', ') }}</td>
|
||||
|
|
|
|||
|
|
@ -45,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}}
|
||||
</td>
|
||||
<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" :id="$mosaic->id" type="mosaic"></x-badge>
|
||||
<livewire:components.badge :status="$mosaic->status" :id="$mosaic->id" type="mosaic" wire:key="{{$mosaic->id}}"></livewire:components.badge>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<div class="flex-1 p-4 bg-white md:w-3/4">
|
||||
@switch($currentTab)
|
||||
@case('downloads')
|
||||
<livewire:projects.tabs.download :project="$project"></livewire:projects.tabs.download>
|
||||
<livewire:projects.tabs.download :project="$project"/>
|
||||
@break
|
||||
@case('mosaics')
|
||||
<livewire:projects.tabs.mosaic :project="$project"></livewire:projects.tabs.mosaic>
|
||||
|
|
|
|||
|
|
@ -26,4 +26,7 @@
|
|||
Broadcast::channel('report.{reportId}', function ($user, $reportId) {
|
||||
return true;
|
||||
});
|
||||
Broadcast::channel('mailing.{mailingId}', function ($user, $mailingId) {
|
||||
return true;
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue