[增添]添加了datasource的setting数据库以及默认值
This commit is contained in:
147
vendor/filament/notifications/src/Actions/Action.php
vendored
Normal file
147
vendor/filament/notifications/src/Actions/Action.php
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Actions;
|
||||
|
||||
use Closure;
|
||||
use Filament\Actions\StaticAction;
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Action extends StaticAction implements Arrayable
|
||||
{
|
||||
protected string $viewIdentifier = 'action';
|
||||
|
||||
protected bool | Closure $shouldMarkAsRead = false;
|
||||
|
||||
protected bool | Closure $shouldMarkAsUnread = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->defaultView(static::LINK_VIEW);
|
||||
|
||||
$this->defaultSize(ActionSize::Small);
|
||||
}
|
||||
|
||||
public function markAsRead(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->shouldMarkAsRead = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function markAsUnread(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->shouldMarkAsUnread = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->getName(),
|
||||
'color' => $this->getColor(),
|
||||
'event' => $this->getEvent(),
|
||||
'eventData' => $this->getEventData(),
|
||||
'dispatchDirection' => $this->getDispatchDirection(),
|
||||
'dispatchToComponent' => $this->getDispatchToComponent(),
|
||||
'extraAttributes' => $this->getExtraAttributes(),
|
||||
'icon' => $this->getIcon(),
|
||||
'iconPosition' => $this->getIconPosition(),
|
||||
'iconSize' => $this->getIconSize(),
|
||||
'isOutlined' => $this->isOutlined(),
|
||||
'isDisabled' => $this->isDisabled(),
|
||||
'label' => $this->getLabel(),
|
||||
'shouldClose' => $this->shouldClose(),
|
||||
'shouldMarkAsRead' => $this->shouldMarkAsRead(),
|
||||
'shouldMarkAsUnread' => $this->shouldMarkAsUnread(),
|
||||
'shouldOpenUrlInNewTab' => $this->shouldOpenUrlInNewTab(),
|
||||
'size' => $this->getSize(),
|
||||
'tooltip' => $this->getTooltip(),
|
||||
'url' => $this->getUrl(),
|
||||
'view' => $this->getView(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
$static = static::make($data['name']);
|
||||
|
||||
$view = $data['view'] ?? null;
|
||||
|
||||
if (filled($view) && ($static->getView() !== $view) && static::isViewSafe($view)) {
|
||||
$static->view($view);
|
||||
}
|
||||
|
||||
if (filled($size = $data['size'] ?? null)) {
|
||||
$static->size($size);
|
||||
}
|
||||
|
||||
$static->close($data['shouldClose'] ?? false);
|
||||
$static->color($data['color'] ?? null);
|
||||
$static->disabled($data['isDisabled'] ?? false);
|
||||
|
||||
match ($data['dispatchDirection'] ?? null) {
|
||||
'self' => $static->dispatchSelf($data['event'] ?? null, $data['eventData'] ?? []),
|
||||
'to' => $static->dispatchTo($data['dispatchToComponent'] ?? null, $data['event'] ?? null, $data['eventData'] ?? []),
|
||||
default => $static->dispatch($data['event'] ?? null, $data['eventData'] ?? [])
|
||||
};
|
||||
|
||||
$static->extraAttributes($data['extraAttributes'] ?? []);
|
||||
$static->icon($data['icon'] ?? null);
|
||||
$static->iconPosition($data['iconPosition'] ?? null);
|
||||
$static->iconSize($data['iconSize'] ?? null);
|
||||
$static->label($data['label'] ?? null);
|
||||
$static->markAsRead($data['shouldMarkAsRead'] ?? false);
|
||||
$static->markAsUnread($data['shouldMarkAsUnread'] ?? false);
|
||||
$static->outlined($data['isOutlined'] ?? false);
|
||||
$static->url($data['url'] ?? null, $data['shouldOpenUrlInNewTab'] ?? false);
|
||||
$static->tooltip($data['tooltip'] ?? null);
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
public function getAlpineClickHandler(): ?string
|
||||
{
|
||||
if (filled($handler = parent::getAlpineClickHandler())) {
|
||||
return $handler;
|
||||
}
|
||||
|
||||
if ($this->shouldMarkAsRead()) {
|
||||
return 'markAsRead()';
|
||||
}
|
||||
|
||||
if ($this->shouldMarkAsUnread()) {
|
||||
return 'markAsUnread()';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param view-string $view
|
||||
*/
|
||||
protected static function isViewSafe(string $view): bool
|
||||
{
|
||||
return Str::startsWith($view, 'filament-actions::');
|
||||
}
|
||||
|
||||
public function shouldMarkAsRead(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->shouldMarkAsRead);
|
||||
}
|
||||
|
||||
public function shouldMarkAsUnread(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->shouldMarkAsUnread);
|
||||
}
|
||||
}
|
||||
88
vendor/filament/notifications/src/Actions/ActionGroup.php
vendored
Normal file
88
vendor/filament/notifications/src/Actions/ActionGroup.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Actions;
|
||||
|
||||
use Filament\Actions\ActionGroup as BaseActionGroup;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property array<Action> $actions
|
||||
*/
|
||||
class ActionGroup extends BaseActionGroup implements Arrayable
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'actions' => collect($this->getActions())->toArray(),
|
||||
'color' => $this->getColor(),
|
||||
'dropdownMaxHeight' => $this->getDropdownMaxHeight(),
|
||||
'dropdownOffset' => $this->getDropdownOffset(),
|
||||
'dropdownPlacement' => $this->getDropdownPlacement(),
|
||||
'dropdownWidth' => $this->getDropdownWidth(),
|
||||
'extraAttributes' => $this->getExtraAttributes(),
|
||||
'hasDropdown' => $this->hasDropdown(),
|
||||
'icon' => $this->getIcon(),
|
||||
'iconPosition' => $this->getIconPosition(),
|
||||
'iconSize' => $this->getIconSize(),
|
||||
'isOutlined' => $this->isOutlined(),
|
||||
'label' => $this->getLabel(),
|
||||
'size' => $this->getSize(),
|
||||
'tooltip' => $this->getTooltip(),
|
||||
'view' => $this->getView(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
$static = static::make(
|
||||
array_map(
|
||||
fn (array $action): Action | ActionGroup => match (array_key_exists('actions', $action)) {
|
||||
true => ActionGroup::fromArray($action),
|
||||
false => Action::fromArray($action),
|
||||
},
|
||||
$data['actions'] ?? [],
|
||||
),
|
||||
);
|
||||
|
||||
$view = $data['view'] ?? null;
|
||||
|
||||
if (filled($view) && ($static->getView() !== $view) && static::isViewSafe($view)) {
|
||||
$static->view($view);
|
||||
}
|
||||
|
||||
if (filled($size = $data['size'] ?? null)) {
|
||||
$static->size($size);
|
||||
}
|
||||
|
||||
$static->color($data['color'] ?? null);
|
||||
$static->dropdown($data['hasDropdown'] ?? false);
|
||||
$static->dropdownMaxHeight($data['dropdownMaxHeight'] ?? null);
|
||||
$static->dropdownOffset($data['dropdownOffset'] ?? null);
|
||||
$static->dropdownPlacement($data['dropdownPlacement'] ?? null);
|
||||
$static->dropdownWidth($data['dropdownWidth'] ?? null);
|
||||
$static->extraAttributes($data['extraAttributes'] ?? []);
|
||||
$static->icon($data['icon'] ?? null);
|
||||
$static->iconPosition($data['iconPosition'] ?? null);
|
||||
$static->iconSize($data['iconSize'] ?? null);
|
||||
$static->label($data['label'] ?? null);
|
||||
$static->outlined($data['isOutlined'] ?? null);
|
||||
$static->tooltip($data['tooltip'] ?? null);
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param view-string $view
|
||||
*/
|
||||
protected static function isViewSafe(string $view): bool
|
||||
{
|
||||
return Str::startsWith($view, 'filament-actions::');
|
||||
}
|
||||
}
|
||||
39
vendor/filament/notifications/src/BroadcastNotification.php
vendored
Normal file
39
vendor/filament/notifications/src/BroadcastNotification.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\Messages\BroadcastMessage;
|
||||
use Illuminate\Notifications\Notification as BaseNotification;
|
||||
|
||||
class BroadcastNotification extends BaseNotification implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function __construct(
|
||||
public array $data,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $notifiable
|
||||
* @return array<string>
|
||||
*/
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['broadcast'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $notifiable
|
||||
*/
|
||||
public function toBroadcast($notifiable): BroadcastMessage
|
||||
{
|
||||
return new BroadcastMessage($this->data);
|
||||
}
|
||||
}
|
||||
35
vendor/filament/notifications/src/Collection.php
vendored
Normal file
35
vendor/filament/notifications/src/Collection.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications;
|
||||
|
||||
use Illuminate\Support\Collection as BaseCollection;
|
||||
use Livewire\Wireable;
|
||||
|
||||
class Collection extends BaseCollection implements Wireable
|
||||
{
|
||||
/**
|
||||
* @param array<array<string, mixed>> $items
|
||||
*/
|
||||
final public function __construct($items = [])
|
||||
{
|
||||
parent::__construct($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<array<string, mixed>>
|
||||
*/
|
||||
public function toLivewire(): array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<array<string, mixed>> $value
|
||||
*/
|
||||
public static function fromLivewire($value): static
|
||||
{
|
||||
return app(static::class, ['items' => $value])->transform(
|
||||
fn (array $notification): Notification => Notification::fromArray($notification),
|
||||
);
|
||||
}
|
||||
}
|
||||
20
vendor/filament/notifications/src/Concerns/CanBeInline.php
vendored
Normal file
20
vendor/filament/notifications/src/Concerns/CanBeInline.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
trait CanBeInline
|
||||
{
|
||||
protected bool $isInline = false;
|
||||
|
||||
public function inline(bool $condition = true): static
|
||||
{
|
||||
$this->isInline = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isInline(): bool
|
||||
{
|
||||
return $this->isInline;
|
||||
}
|
||||
}
|
||||
34
vendor/filament/notifications/src/Concerns/HasActions.php
vendored
Normal file
34
vendor/filament/notifications/src/Concerns/HasActions.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Filament\Notifications\Actions\Action;
|
||||
use Filament\Notifications\Actions\ActionGroup;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
trait HasActions
|
||||
{
|
||||
/**
|
||||
* @var array<Action | ActionGroup> | ActionGroup | Closure
|
||||
*/
|
||||
protected array | ActionGroup | Closure $actions = [];
|
||||
|
||||
/**
|
||||
* @param array<Action | ActionGroup> | ActionGroup | Closure $actions
|
||||
*/
|
||||
public function actions(array | ActionGroup | Closure $actions): static
|
||||
{
|
||||
$this->actions = $actions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Action | ActionGroup>
|
||||
*/
|
||||
public function getActions(): array
|
||||
{
|
||||
return Arr::wrap($this->evaluate($this->actions));
|
||||
}
|
||||
}
|
||||
22
vendor/filament/notifications/src/Concerns/HasBody.php
vendored
Normal file
22
vendor/filament/notifications/src/Concerns/HasBody.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait HasBody
|
||||
{
|
||||
protected string | Closure | null $body = null;
|
||||
|
||||
public function body(string | Closure | null $body): static
|
||||
{
|
||||
$this->body = $body;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBody(): ?string
|
||||
{
|
||||
return $this->evaluate($this->body);
|
||||
}
|
||||
}
|
||||
22
vendor/filament/notifications/src/Concerns/HasDate.php
vendored
Normal file
22
vendor/filament/notifications/src/Concerns/HasDate.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait HasDate
|
||||
{
|
||||
protected string | Closure | null $date = null;
|
||||
|
||||
public function date(string | Closure | null $date): static
|
||||
{
|
||||
$this->date = $date;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDate(): ?string
|
||||
{
|
||||
return $this->evaluate($this->date);
|
||||
}
|
||||
}
|
||||
36
vendor/filament/notifications/src/Concerns/HasDuration.php
vendored
Normal file
36
vendor/filament/notifications/src/Concerns/HasDuration.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait HasDuration
|
||||
{
|
||||
protected int | string | Closure $duration = 6000;
|
||||
|
||||
public function duration(int | string | Closure | null $duration): static
|
||||
{
|
||||
$this->duration = $duration ?? 'persistent';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDuration(): int | string
|
||||
{
|
||||
return $this->evaluate($this->duration) ?? 'persistent';
|
||||
}
|
||||
|
||||
public function seconds(float $seconds): static
|
||||
{
|
||||
$this->duration((int) ($seconds * 1000));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function persistent(): static
|
||||
{
|
||||
$this->duration('persistent');
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
24
vendor/filament/notifications/src/Concerns/HasIcon.php
vendored
Normal file
24
vendor/filament/notifications/src/Concerns/HasIcon.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Filament\Support\Concerns\HasIcon as BaseTrait;
|
||||
use Filament\Support\Facades\FilamentIcon;
|
||||
|
||||
trait HasIcon
|
||||
{
|
||||
use BaseTrait {
|
||||
getIcon as baseGetIcon;
|
||||
}
|
||||
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return $this->baseGetIcon() ?? match ($this->getStatus()) {
|
||||
'danger' => FilamentIcon::resolve('notifications::notification.danger') ?? 'heroicon-o-x-circle',
|
||||
'info' => FilamentIcon::resolve('notifications::notification.info') ?? 'heroicon-o-information-circle',
|
||||
'success' => FilamentIcon::resolve('notifications::notification.success') ?? 'heroicon-o-check-circle',
|
||||
'warning' => FilamentIcon::resolve('notifications::notification.warning') ?? 'heroicon-o-exclamation-circle',
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
20
vendor/filament/notifications/src/Concerns/HasIconColor.php
vendored
Normal file
20
vendor/filament/notifications/src/Concerns/HasIconColor.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Filament\Support\Concerns\HasIconColor as BaseTrait;
|
||||
|
||||
trait HasIconColor
|
||||
{
|
||||
use BaseTrait {
|
||||
getIconColor as baseGetIconColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
|
||||
*/
|
||||
public function getIconColor(): string | array | null
|
||||
{
|
||||
return $this->baseGetIconColor() ?? $this->getStatus();
|
||||
}
|
||||
}
|
||||
20
vendor/filament/notifications/src/Concerns/HasId.php
vendored
Normal file
20
vendor/filament/notifications/src/Concerns/HasId.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
trait HasId
|
||||
{
|
||||
protected string $id;
|
||||
|
||||
public function id(string $id): static
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
42
vendor/filament/notifications/src/Concerns/HasStatus.php
vendored
Normal file
42
vendor/filament/notifications/src/Concerns/HasStatus.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait HasStatus
|
||||
{
|
||||
protected string | Closure | null $status = null;
|
||||
|
||||
public function status(string | Closure | null $status): static
|
||||
{
|
||||
$this->status = $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStatus(): ?string
|
||||
{
|
||||
return $this->evaluate($this->status);
|
||||
}
|
||||
|
||||
public function danger(): static
|
||||
{
|
||||
return $this->status('danger');
|
||||
}
|
||||
|
||||
public function info(): static
|
||||
{
|
||||
return $this->status('info');
|
||||
}
|
||||
|
||||
public function success(): static
|
||||
{
|
||||
return $this->status('success');
|
||||
}
|
||||
|
||||
public function warning(): static
|
||||
{
|
||||
return $this->status('warning');
|
||||
}
|
||||
}
|
||||
22
vendor/filament/notifications/src/Concerns/HasTitle.php
vendored
Normal file
22
vendor/filament/notifications/src/Concerns/HasTitle.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait HasTitle
|
||||
{
|
||||
protected string | Closure | null $title = null;
|
||||
|
||||
public function title(string | Closure | null $title): static
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->evaluate($this->title);
|
||||
}
|
||||
}
|
||||
48
vendor/filament/notifications/src/DatabaseNotification.php
vendored
Normal file
48
vendor/filament/notifications/src/DatabaseNotification.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\Notification as BaseNotification;
|
||||
|
||||
class DatabaseNotification extends BaseNotification implements Arrayable, ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function __construct(
|
||||
public array $data,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $notifiable
|
||||
* @return array<string>
|
||||
*/
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $notifiable
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toDatabase($notifiable): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
41
vendor/filament/notifications/src/Events/DatabaseNotificationsSent.php
vendored
Normal file
41
vendor/filament/notifications/src/Events/DatabaseNotificationsSent.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class DatabaseNotificationsSent implements ShouldBroadcast
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
public Model | Authenticatable $user;
|
||||
|
||||
public function __construct(Model | Authenticatable $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function broadcastOn(): string
|
||||
{
|
||||
if (method_exists($this->user, 'receivesBroadcastNotificationsOn')) {
|
||||
return new PrivateChannel($this->user->receivesBroadcastNotificationsOn());
|
||||
}
|
||||
|
||||
$userClass = str_replace('\\', '.', $this->user::class);
|
||||
|
||||
return new PrivateChannel("{$userClass}.{$this->user->getKey()}");
|
||||
}
|
||||
|
||||
public function broadcastAs(): string
|
||||
{
|
||||
return 'database-notifications.sent';
|
||||
}
|
||||
}
|
||||
178
vendor/filament/notifications/src/Livewire/DatabaseNotifications.php
vendored
Normal file
178
vendor/filament/notifications/src/Livewire/DatabaseNotifications.php
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Livewire;
|
||||
|
||||
use Carbon\CarbonInterface;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Notifications\DatabaseNotification;
|
||||
use Illuminate\Notifications\DatabaseNotificationCollection;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class DatabaseNotifications extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public static bool $isPaginated = true;
|
||||
|
||||
public static ?string $trigger = null;
|
||||
|
||||
public static ?string $pollingInterval = '30s';
|
||||
|
||||
public static ?string $authGuard = null;
|
||||
|
||||
#[On('databaseNotificationsSent')]
|
||||
public function refresh(): void
|
||||
{
|
||||
}
|
||||
|
||||
#[On('notificationClosed')]
|
||||
public function removeNotification(string $id): void
|
||||
{
|
||||
$this->getNotificationsQuery()
|
||||
->where('id', $id)
|
||||
->delete();
|
||||
}
|
||||
|
||||
#[On('markedNotificationAsRead')]
|
||||
public function markNotificationAsRead(string $id): void
|
||||
{
|
||||
$this->getNotificationsQuery()
|
||||
->where('id', $id)
|
||||
->update(['read_at' => now()]);
|
||||
}
|
||||
|
||||
#[On('markedNotificationAsUnread')]
|
||||
public function markNotificationAsUnread(string $id): void
|
||||
{
|
||||
$this->getNotificationsQuery()
|
||||
->where('id', $id)
|
||||
->update(['read_at' => null]);
|
||||
}
|
||||
|
||||
public function clearNotifications(): void
|
||||
{
|
||||
$this->getNotificationsQuery()->delete();
|
||||
}
|
||||
|
||||
public function markAllNotificationsAsRead(): void
|
||||
{
|
||||
$this->getUnreadNotificationsQuery()->update(['read_at' => now()]);
|
||||
}
|
||||
|
||||
public function getNotifications(): DatabaseNotificationCollection | Paginator
|
||||
{
|
||||
if (! $this->isPaginated()) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
return $this->getNotificationsQuery()->get();
|
||||
}
|
||||
|
||||
return $this->getNotificationsQuery()->simplePaginate(50, pageName: 'database-notifications-page');
|
||||
}
|
||||
|
||||
public function isPaginated(): bool
|
||||
{
|
||||
return static::$isPaginated;
|
||||
}
|
||||
|
||||
public function getNotificationsQuery(): Builder | Relation
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
return $this->getUser()->notifications()->where('data->format', 'filament');
|
||||
}
|
||||
|
||||
public function getUnreadNotificationsQuery(): Builder | Relation
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
return $this->getNotificationsQuery()->unread();
|
||||
}
|
||||
|
||||
public function getUnreadNotificationsCount(): int
|
||||
{
|
||||
return $this->getUnreadNotificationsQuery()->count();
|
||||
}
|
||||
|
||||
public function getPollingInterval(): ?string
|
||||
{
|
||||
return static::$pollingInterval;
|
||||
}
|
||||
|
||||
public function getTrigger(): ?View
|
||||
{
|
||||
$viewPath = static::$trigger;
|
||||
|
||||
if (blank($viewPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return view($viewPath);
|
||||
}
|
||||
|
||||
public function getUser(): Model | Authenticatable | null
|
||||
{
|
||||
return auth(static::$authGuard)->user();
|
||||
}
|
||||
|
||||
public function getBroadcastChannel(): ?string
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
if (! $user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method_exists($user, 'receivesBroadcastNotificationsOn')) {
|
||||
return $user->receivesBroadcastNotificationsOn();
|
||||
}
|
||||
|
||||
$userClass = str_replace('\\', '.', $user::class);
|
||||
|
||||
return "{$userClass}.{$user->getKey()}";
|
||||
}
|
||||
|
||||
public function getNotification(DatabaseNotification $notification): Notification
|
||||
{
|
||||
return Notification::fromDatabase($notification)
|
||||
->date($this->formatNotificationDate($notification->getAttributeValue('created_at')));
|
||||
}
|
||||
|
||||
protected function formatNotificationDate(CarbonInterface $date): string
|
||||
{
|
||||
return $date->diffForHumans();
|
||||
}
|
||||
|
||||
public static function trigger(?string $trigger): void
|
||||
{
|
||||
static::$trigger = $trigger;
|
||||
}
|
||||
|
||||
public static function pollingInterval(?string $interval): void
|
||||
{
|
||||
static::$pollingInterval = $interval;
|
||||
}
|
||||
|
||||
public static function authGuard(?string $guard): void
|
||||
{
|
||||
static::$authGuard = $guard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
public function queryStringHandlesPagination(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('filament-notifications::database-notifications');
|
||||
}
|
||||
}
|
||||
126
vendor/filament/notifications/src/Livewire/Notifications.php
vendored
Normal file
126
vendor/filament/notifications/src/Livewire/Notifications.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Livewire;
|
||||
|
||||
use Filament\Notifications\Collection;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Component;
|
||||
|
||||
class Notifications extends Component
|
||||
{
|
||||
// Used to check if Livewire messages should trigger notification animations.
|
||||
public bool $isFilamentNotificationsComponent = true;
|
||||
|
||||
public Collection $notifications;
|
||||
|
||||
public static Alignment $alignment = Alignment::Right;
|
||||
|
||||
public static VerticalAlignment $verticalAlignment = VerticalAlignment::Start;
|
||||
|
||||
public static ?string $authGuard = null;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->notifications = new Collection();
|
||||
$this->pullNotificationsFromSession();
|
||||
}
|
||||
|
||||
#[On('notificationsSent')]
|
||||
public function pullNotificationsFromSession(): void
|
||||
{
|
||||
foreach (session()->pull('filament.notifications') ?? [] as $notification) {
|
||||
$notification = Notification::fromArray($notification);
|
||||
|
||||
$this->pushNotification($notification);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $notification
|
||||
*/
|
||||
#[On('notificationSent')]
|
||||
public function pushNotificationFromEvent(array $notification): void
|
||||
{
|
||||
$notification = Notification::fromArray($notification);
|
||||
|
||||
$this->pushNotification($notification);
|
||||
}
|
||||
|
||||
#[On('notificationClosed')]
|
||||
public function removeNotification(string $id): void
|
||||
{
|
||||
if (! $this->notifications->has($id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->notifications->forget($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $notification
|
||||
*/
|
||||
public function handleBroadcastNotification(array $notification): void
|
||||
{
|
||||
if (($notification['format'] ?? null) !== 'filament') {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->pushNotification(Notification::fromArray($notification));
|
||||
}
|
||||
|
||||
protected function pushNotification(Notification $notification): void
|
||||
{
|
||||
$this->notifications->put(
|
||||
$notification->getId(),
|
||||
$notification,
|
||||
);
|
||||
}
|
||||
|
||||
public function getUser(): Model | Authenticatable | null
|
||||
{
|
||||
return auth(static::$authGuard)->user();
|
||||
}
|
||||
|
||||
public function getBroadcastChannel(): ?string
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
if (! $user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method_exists($user, 'receivesBroadcastNotificationsOn')) {
|
||||
return $user->receivesBroadcastNotificationsOn();
|
||||
}
|
||||
|
||||
$userClass = str_replace('\\', '.', $user::class);
|
||||
|
||||
return "{$userClass}.{$user->getKey()}";
|
||||
}
|
||||
|
||||
public static function alignment(Alignment $alignment): void
|
||||
{
|
||||
static::$alignment = $alignment;
|
||||
}
|
||||
|
||||
public static function verticalAlignment(VerticalAlignment $alignment): void
|
||||
{
|
||||
static::$verticalAlignment = $alignment;
|
||||
}
|
||||
|
||||
public static function authGuard(?string $guard): void
|
||||
{
|
||||
static::$authGuard = $guard;
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('filament-notifications::notifications');
|
||||
}
|
||||
}
|
||||
313
vendor/filament/notifications/src/Notification.php
vendored
Normal file
313
vendor/filament/notifications/src/Notification.php
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications;
|
||||
|
||||
use Filament\Notifications\Actions\Action;
|
||||
use Filament\Notifications\Actions\ActionGroup;
|
||||
use Filament\Notifications\Events\DatabaseNotificationsSent;
|
||||
use Filament\Notifications\Livewire\Notifications;
|
||||
use Filament\Support\Components\ViewComponent;
|
||||
use Filament\Support\Concerns\HasColor;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\DatabaseNotification as DatabaseNotificationModel;
|
||||
use Illuminate\Notifications\Messages\BroadcastMessage;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use PHPUnit\Framework\Assert;
|
||||
|
||||
class Notification extends ViewComponent implements Arrayable
|
||||
{
|
||||
use Concerns\CanBeInline;
|
||||
use Concerns\HasActions;
|
||||
use Concerns\HasBody;
|
||||
use Concerns\HasDate;
|
||||
use Concerns\HasDuration;
|
||||
use Concerns\HasIcon;
|
||||
use Concerns\HasIconColor;
|
||||
use Concerns\HasId;
|
||||
use Concerns\HasStatus;
|
||||
use Concerns\HasTitle;
|
||||
use HasColor;
|
||||
|
||||
/**
|
||||
* @var view-string
|
||||
*/
|
||||
protected string $view = 'filament-notifications::notification';
|
||||
|
||||
protected string $viewIdentifier = 'notification';
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected array $safeViews = [];
|
||||
|
||||
public function __construct(string $id)
|
||||
{
|
||||
$this->id($id);
|
||||
}
|
||||
|
||||
public static function make(?string $id = null): static
|
||||
{
|
||||
$static = app(static::class, ['id' => $id ?? Str::orderedUuid()]);
|
||||
$static->configure();
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getViewData(): array
|
||||
{
|
||||
return $this->viewData;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->getId(),
|
||||
'actions' => array_map(fn (Action | ActionGroup $action): array => $action->toArray(), $this->getActions()),
|
||||
'body' => $this->getBody(),
|
||||
'color' => $this->getColor(),
|
||||
'duration' => $this->getDuration(),
|
||||
'icon' => $this->getIcon(),
|
||||
'iconColor' => $this->getIconColor(),
|
||||
'status' => $this->getStatus(),
|
||||
'title' => $this->getTitle(),
|
||||
'view' => $this->getView(),
|
||||
'viewData' => $this->getViewData(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
$static = static::make($data['id'] ?? Str::random());
|
||||
|
||||
// If the container constructs an instance of child class
|
||||
// instead of the current class, we should run `fromArray()`
|
||||
// on the child class instead.
|
||||
if (
|
||||
($static::class !== self::class) &&
|
||||
(get_called_class() === self::class)
|
||||
) {
|
||||
return $static::fromArray($data);
|
||||
}
|
||||
|
||||
$static->actions(
|
||||
array_map(
|
||||
fn (array $action): Action | ActionGroup => match (array_key_exists('actions', $action)) {
|
||||
true => ActionGroup::fromArray($action),
|
||||
false => Action::fromArray($action),
|
||||
},
|
||||
$data['actions'] ?? [],
|
||||
),
|
||||
);
|
||||
|
||||
$view = $data['view'] ?? null;
|
||||
|
||||
if (filled($view) && ($static->getView() !== $view) && $static->isViewSafe($view)) {
|
||||
$static->view($data['view']);
|
||||
}
|
||||
|
||||
$static->viewData($data['viewData'] ?? []);
|
||||
$static->body($data['body'] ?? null);
|
||||
$static->color($data['color'] ?? null);
|
||||
$static->duration($data['duration'] ?? $static->getDuration());
|
||||
$static->status($data['status'] ?? $static->getStatus());
|
||||
$static->icon($data['icon'] ?? $static->getIcon());
|
||||
$static->iconColor($data['iconColor'] ?? $static->getIconColor());
|
||||
$static->title($data['title'] ?? null);
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
protected function isViewSafe(string $view): bool
|
||||
{
|
||||
return in_array($view, $this->safeViews, strict: true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string | array<string> $safeViews
|
||||
*/
|
||||
public function safeViews(string | array $safeViews): static
|
||||
{
|
||||
$this->safeViews = [
|
||||
...$this->safeViews,
|
||||
...Arr::wrap($safeViews),
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function send(): static
|
||||
{
|
||||
session()->push(
|
||||
'filament.notifications',
|
||||
$this->toArray(),
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model | Authenticatable | Collection | array<Model | Authenticatable> $users
|
||||
*/
|
||||
public function broadcast(Model | Authenticatable | Collection | array $users): static
|
||||
{
|
||||
if (! is_iterable($users)) {
|
||||
$users = [$users];
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user->notify($this->toBroadcast());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model | Authenticatable | Collection | array<Model | Authenticatable> $users
|
||||
*/
|
||||
public function sendToDatabase(Model | Authenticatable | Collection | array $users, bool $isEventDispatched = false): static
|
||||
{
|
||||
if (! is_iterable($users)) {
|
||||
$users = [$users];
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user->notify($this->toDatabase());
|
||||
|
||||
if ($isEventDispatched) {
|
||||
DatabaseNotificationsSent::dispatch($user);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toBroadcast(): BroadcastNotification
|
||||
{
|
||||
$data = $this->toArray();
|
||||
$data['format'] = 'filament';
|
||||
|
||||
return new BroadcastNotification($data);
|
||||
}
|
||||
|
||||
public function toDatabase(): DatabaseNotification
|
||||
{
|
||||
return new DatabaseNotification($this->getDatabaseMessage());
|
||||
}
|
||||
|
||||
public function getBroadcastMessage(): BroadcastMessage
|
||||
{
|
||||
$data = $this->toArray();
|
||||
$data['format'] = 'filament';
|
||||
|
||||
return new BroadcastMessage($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getDatabaseMessage(): array
|
||||
{
|
||||
$data = $this->toArray();
|
||||
$data['duration'] = 'persistent';
|
||||
$data['format'] = 'filament';
|
||||
unset($data['id']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function fromDatabase(DatabaseNotificationModel $notification): static
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
$static = static::fromArray($notification->data);
|
||||
$static->id($notification->getKey());
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
public static function assertNotified(Notification | string | null $notification = null): void
|
||||
{
|
||||
$notificationsLivewireComponent = new Notifications();
|
||||
$notificationsLivewireComponent->mount();
|
||||
$notifications = $notificationsLivewireComponent->notifications;
|
||||
|
||||
$expectedNotification = null;
|
||||
|
||||
Assert::assertIsArray($notifications->toArray());
|
||||
|
||||
if (is_string($notification)) {
|
||||
$expectedNotification = $notifications->first(fn (Notification $mountedNotification): bool => $mountedNotification->title === $notification);
|
||||
}
|
||||
|
||||
if ($notification instanceof Notification) {
|
||||
$expectedNotification = $notifications->first(fn (Notification $mountedNotification, string $key): bool => $mountedNotification->id === $key);
|
||||
}
|
||||
|
||||
if (blank($notification)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert::assertNotNull($expectedNotification, 'A notification was not sent');
|
||||
|
||||
if ($notification instanceof Notification) {
|
||||
Assert::assertSame(
|
||||
collect($expectedNotification)->except(['id'])->toArray(),
|
||||
collect($notification->toArray())->except(['id'])->toArray()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Assert::assertSame($expectedNotification->title, $notification);
|
||||
}
|
||||
|
||||
public static function assertNotNotified(Notification | string | null $notification = null): void
|
||||
{
|
||||
$notificationsLivewireComponent = new Notifications();
|
||||
$notificationsLivewireComponent->mount();
|
||||
$notifications = $notificationsLivewireComponent->notifications;
|
||||
|
||||
$expectedNotification = null;
|
||||
|
||||
Assert::assertIsArray($notifications->toArray());
|
||||
|
||||
if (is_string($notification)) {
|
||||
$expectedNotification = $notifications->first(fn (Notification $mountedNotification): bool => $mountedNotification->title === $notification);
|
||||
}
|
||||
|
||||
if ($notification instanceof Notification) {
|
||||
$expectedNotification = $notifications->first(fn (Notification $mountedNotification, string $key): bool => $mountedNotification->id === $key);
|
||||
}
|
||||
|
||||
if (blank($notification)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($notification instanceof Notification) {
|
||||
Assert::assertNotSame(
|
||||
collect($expectedNotification)->except(['id'])->toArray(),
|
||||
collect($notification->toArray())->except(['id'])->toArray(),
|
||||
'The notification with the given configration was sent'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($expectedNotification instanceof Notification) {
|
||||
Assert::assertNotSame(
|
||||
$expectedNotification->title,
|
||||
$notification,
|
||||
'The notification with the given title was sent'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
vendor/filament/notifications/src/NotificationsServiceProvider.php
vendored
Normal file
57
vendor/filament/notifications/src/NotificationsServiceProvider.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications;
|
||||
|
||||
use Filament\Notifications\Livewire\DatabaseNotifications;
|
||||
use Filament\Notifications\Livewire\Notifications;
|
||||
use Filament\Notifications\Testing\TestsNotifications;
|
||||
use Filament\Support\Assets\Js;
|
||||
use Filament\Support\Facades\FilamentAsset;
|
||||
use Livewire\Component;
|
||||
use Livewire\Features\SupportTesting\Testable;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\LaravelPackageTools\Package;
|
||||
use Spatie\LaravelPackageTools\PackageServiceProvider;
|
||||
|
||||
use function Livewire\on;
|
||||
use function Livewire\store;
|
||||
|
||||
class NotificationsServiceProvider extends PackageServiceProvider
|
||||
{
|
||||
public function configurePackage(Package $package): void
|
||||
{
|
||||
$package
|
||||
->name('filament-notifications')
|
||||
->hasTranslations()
|
||||
->hasViews();
|
||||
}
|
||||
|
||||
public function packageBooted(): void
|
||||
{
|
||||
FilamentAsset::register([
|
||||
Js::make('notifications', __DIR__ . '/../dist/index.js'),
|
||||
], 'filament/notifications');
|
||||
|
||||
Livewire::component('database-notifications', DatabaseNotifications::class);
|
||||
|
||||
Livewire::component('notifications', Notifications::class);
|
||||
|
||||
on('dehydrate', function (Component $component) {
|
||||
if (! Livewire::isLivewireRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (store($component)->has('redirect')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count(session()->get('filament.notifications') ?? []) <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$component->dispatch('notificationsSent');
|
||||
});
|
||||
|
||||
Testable::mixin(new TestsNotifications());
|
||||
}
|
||||
}
|
||||
15
vendor/filament/notifications/src/Testing/Autoload.php
vendored
Normal file
15
vendor/filament/notifications/src/Testing/Autoload.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Testing;
|
||||
|
||||
use Filament\Notifications\Notification;
|
||||
|
||||
/**
|
||||
* @return TestCall | TestCase | mixed
|
||||
*/
|
||||
function assertNotified(Notification | string | null $notification = null)
|
||||
{
|
||||
Notification::assertNotified($notification);
|
||||
|
||||
return test();
|
||||
}
|
||||
34
vendor/filament/notifications/src/Testing/TestsNotifications.php
vendored
Normal file
34
vendor/filament/notifications/src/Testing/TestsNotifications.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Notifications\Testing;
|
||||
|
||||
use Closure;
|
||||
use Filament\Notifications\Notification;
|
||||
use Livewire\Component;
|
||||
use Livewire\Features\SupportTesting\Testable;
|
||||
|
||||
/**
|
||||
* @method Component instance()
|
||||
*
|
||||
* @mixin Testable
|
||||
*/
|
||||
class TestsNotifications
|
||||
{
|
||||
public function assertNotified(): Closure
|
||||
{
|
||||
return function (Notification | string | null $notification = null): static {
|
||||
Notification::assertNotified($notification);
|
||||
|
||||
return $this;
|
||||
};
|
||||
}
|
||||
|
||||
public function assertNotNotified(): Closure
|
||||
{
|
||||
return function (Notification | string | null $notification = null): static {
|
||||
Notification::assertNotNotified($notification);
|
||||
|
||||
return $this;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user