mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Fix popup toast messages (Remove Flasher) (#16090)
* Remove flasher Just use a bit of custom code to interface with toastr js This is able to retain our custom theme and work properly * Fix style issues * Missed reference rename * Remove test code :) * Fix a missed rename * Fix one more missed reference * Fix typo
This commit is contained in:
@@ -54,32 +54,26 @@ class Checks
|
||||
if ($user->isAdmin()) {
|
||||
$notifications = Notification::isUnread($user)->where('severity', '>', Severity::Ok->value)->get();
|
||||
foreach ($notifications as $notification) {
|
||||
flash()
|
||||
->using('template.librenms')
|
||||
->title($notification->title)
|
||||
->addWarning("<a href='notifications/'>$notification->body</a>");
|
||||
toast()->warning($notification->title, "<a href='notifications/'>$notification->body</a>");
|
||||
}
|
||||
|
||||
$warn_sec = Config::get('rrd.step', 300) * 3;
|
||||
if (Device::isUp()->where('last_polled', '<=', Carbon::now()->subSeconds($warn_sec))->exists()) {
|
||||
$warn_min = $warn_sec / 60;
|
||||
flash()
|
||||
->using('template.librenms')
|
||||
->title('Devices unpolled')
|
||||
->addWarning('<a href="poller/log?filter=unpolled/">It appears as though you have some devices that haven\'t completed polling within the last ' . $warn_min . ' minutes, you may want to check that out :)</a>');
|
||||
toast()->warning('Devices unpolled', '<a href="poller/log?filter=unpolled/">It appears as though you have some devices that haven\'t completed polling within the last ' . $warn_min . ' minutes, you may want to check that out :)</a>');
|
||||
}
|
||||
|
||||
// Directory access checks
|
||||
$rrd_dir = Config::get('rrd_dir');
|
||||
if (! is_dir($rrd_dir)) {
|
||||
flash()->addError("RRD Directory is missing ($rrd_dir). Graphing may fail. <a href=" . url('validate') . '>Validate your install</a>');
|
||||
toast()->error("RRD Directory is missing ($rrd_dir). Graphing may fail. <a href=" . url('validate') . '>Validate your install</a>');
|
||||
}
|
||||
|
||||
$temp_dir = Config::get('temp_dir');
|
||||
if (! is_dir($temp_dir)) {
|
||||
flash()->addError("Temp Directory is missing ($temp_dir). Graphing may fail. <a href=" . url('validate') . '>Validate your install</a>');
|
||||
toast()->error("Temp Directory is missing ($temp_dir). Graphing may fail. <a href=" . url('validate') . '>Validate your install</a>');
|
||||
} elseif (! is_writable($temp_dir)) {
|
||||
flash()->addError("Temp Directory is not writable ($temp_dir). Graphing may fail. <a href='" . url('validate') . "'>Validate your install</a>");
|
||||
toast()->error("Temp Directory is not writable ($temp_dir). Graphing may fail. <a href='" . url('validate') . "'>Validate your install</a>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -74,7 +74,7 @@ class SocialiteController extends Controller
|
||||
if (array_key_exists('error', $request->query())) {
|
||||
$error = $request->query('error');
|
||||
$error_description = $request->query('error_description');
|
||||
flash()->addError($error . ': ' . $error_description);
|
||||
toast()->error($error . ': ' . $error_description);
|
||||
|
||||
return redirect()->route('login');
|
||||
}
|
||||
@@ -121,7 +121,7 @@ class SocialiteController extends Controller
|
||||
|
||||
return redirect()->intended();
|
||||
} catch (AuthenticationException $e) {
|
||||
flash()->addError($e->getMessage());
|
||||
toast()->error($e->getMessage());
|
||||
}
|
||||
|
||||
return redirect()->route('login');
|
||||
|
@@ -26,6 +26,7 @@
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Interfaces\ToastInterface;
|
||||
use App\Models\User;
|
||||
use App\Models\UserPref;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -37,14 +38,14 @@ use Session;
|
||||
|
||||
class TwoFactorController extends Controller
|
||||
{
|
||||
public function verifyTwoFactor(Request $request)
|
||||
public function verifyTwoFactor(Request $request, ToastInterface $toast)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'twofactor' => 'required|numeric',
|
||||
]);
|
||||
|
||||
try {
|
||||
$this->checkToken($request->user(), $request->input('twofactor'));
|
||||
$this->checkToken($request->user(), $request->input('twofactor'), $toast);
|
||||
} catch (AuthenticationException $e) {
|
||||
return redirect()->route('2fa.form')->withErrors($e->getMessage());
|
||||
}
|
||||
@@ -54,7 +55,7 @@ class TwoFactorController extends Controller
|
||||
UserPref::forgetPref(auth()->user(), 'twofactor');
|
||||
$request->session()->forget(['twofactor', 'twofactorremove']);
|
||||
|
||||
flash()->addInfo(__('TwoFactor auth removed.'));
|
||||
$toast->info(__('TwoFactor auth removed.'));
|
||||
|
||||
return redirect('preferences');
|
||||
}
|
||||
@@ -153,7 +154,7 @@ class TwoFactorController extends Controller
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
private function checkToken($user, $token)
|
||||
private function checkToken($user, $token, ToastInterface $toast)
|
||||
{
|
||||
if (! $token) {
|
||||
throw new AuthenticationException(__('No Two-Factor Token entered.'));
|
||||
@@ -192,7 +193,7 @@ class TwoFactorController extends Controller
|
||||
|
||||
// notify if added
|
||||
if (Session::has('twofactoradd')) {
|
||||
flash()->addSuccess(__('TwoFactor auth added.'));
|
||||
$toast->success(__('TwoFactor auth added.'));
|
||||
Session::forget('twofactoradd');
|
||||
}
|
||||
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Interfaces\ToastInterface;
|
||||
use App\Models\DeviceGroup;
|
||||
use Flasher\Prime\FlasherInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use LibreNMS\Alerting\QueryBuilderFilter;
|
||||
@@ -49,7 +49,7 @@ class DeviceGroupController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request, FlasherInterface $flasher)
|
||||
public function store(Request $request, ToastInterface $toast)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|unique:device_groups',
|
||||
@@ -67,7 +67,7 @@ class DeviceGroupController extends Controller
|
||||
$deviceGroup->devices()->sync($request->devices);
|
||||
}
|
||||
|
||||
$flasher->addSuccess(__('Device Group :name created', ['name' => htmlentities($deviceGroup->name)]));
|
||||
$toast->success(__('Device Group :name created', ['name' => htmlentities($deviceGroup->name)]));
|
||||
|
||||
return redirect()->route('device-groups.index');
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class DeviceGroupController extends Controller
|
||||
* @param \App\Models\DeviceGroup $deviceGroup
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, DeviceGroup $deviceGroup, FlasherInterface $flasher)
|
||||
public function update(Request $request, DeviceGroup $deviceGroup, ToastInterface $toast)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => [
|
||||
@@ -143,9 +143,9 @@ class DeviceGroupController extends Controller
|
||||
if ($deviceGroup->isDirty() || $devices_updated) {
|
||||
try {
|
||||
if ($deviceGroup->save() || $devices_updated) {
|
||||
$flasher->addSuccess(__('Device Group :name updated', ['name' => htmlentities($deviceGroup->name)]));
|
||||
$toast->success(__('Device Group :name updated', ['name' => htmlentities($deviceGroup->name)]));
|
||||
} else {
|
||||
$flasher->addError(__('Failed to save'));
|
||||
$toast->error(__('Failed to save'));
|
||||
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
@@ -155,7 +155,7 @@ class DeviceGroupController extends Controller
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$flasher->addInfo(__('No changes made'));
|
||||
$toast->info(__('No changes made'));
|
||||
}
|
||||
|
||||
return redirect()->route('device-groups.index');
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Interfaces\ToastInterface;
|
||||
use App\Models\PortGroup;
|
||||
use Flasher\Prime\FlasherInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
@@ -39,7 +39,7 @@ class PortGroupController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request, FlasherInterface $flasher)
|
||||
public function store(Request $request, ToastInterface $toast)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|unique:port_groups',
|
||||
@@ -48,7 +48,7 @@ class PortGroupController extends Controller
|
||||
$portGroup = PortGroup::make($request->only(['name', 'desc']));
|
||||
$portGroup->save();
|
||||
|
||||
$flasher->addSuccess(__('Port Group :name created', ['name' => $portGroup->name]));
|
||||
$toast->success(__('Port Group :name created', ['name' => $portGroup->name]));
|
||||
|
||||
return redirect()->route('port-groups.index');
|
||||
}
|
||||
@@ -73,7 +73,7 @@ class PortGroupController extends Controller
|
||||
* @param \App\Models\PortGroup $portGroup
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, PortGroup $portGroup, FlasherInterface $flasher)
|
||||
public function update(Request $request, PortGroup $portGroup, ToastInterface $toast)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => [
|
||||
@@ -90,9 +90,9 @@ class PortGroupController extends Controller
|
||||
$portGroup->fill($request->only(['name', 'desc']));
|
||||
|
||||
if ($portGroup->save()) {
|
||||
$flasher->addSuccess(__('Port Group :name updated', ['name' => $portGroup->name]));
|
||||
$toast->success(__('Port Group :name updated', ['name' => $portGroup->name]));
|
||||
} else {
|
||||
$flasher->addError(__('Failed to save'));
|
||||
$toast->error(__('Failed to save'));
|
||||
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Interfaces\ToastInterface;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ServiceController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request, ToastInterface $toast)
|
||||
{
|
||||
$request = [
|
||||
'service_name' => 'required|string|unique:service',
|
||||
@@ -44,7 +45,7 @@ class ServiceController extends Controller
|
||||
);
|
||||
$service->save();
|
||||
|
||||
flash()->addSuccess(__('Service :name created', ['name' => $service->service_name]));
|
||||
$toast->success(__('Service :name created', ['name' => $service->service_name]));
|
||||
|
||||
return redirect()->route('services.templates.index');
|
||||
}
|
||||
|
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Interfaces\ToastInterface;
|
||||
use App\Models\Device;
|
||||
use App\Models\DeviceGroup;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceTemplate;
|
||||
use Flasher\Prime\FlasherInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use LibreNMS\Alerting\QueryBuilderFilter;
|
||||
@@ -60,7 +60,7 @@ class ServiceTemplateController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function store(Request $request, FlasherInterface $flasher)
|
||||
public function store(Request $request, ToastInterface $toast)
|
||||
{
|
||||
$this->validate(
|
||||
$request, [
|
||||
@@ -105,7 +105,7 @@ class ServiceTemplateController extends Controller
|
||||
}
|
||||
|
||||
$template->groups()->sync($request->groups);
|
||||
$flasher->addSuccess(__('Service Template :name created', ['name' => $template->name]));
|
||||
$toast->success(__('Service Template :name created', ['name' => $template->name]));
|
||||
|
||||
return redirect()->route('services.templates.index');
|
||||
}
|
||||
@@ -146,7 +146,7 @@ class ServiceTemplateController extends Controller
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function update(Request $request, ServiceTemplate $template, FlasherInterface $flasher)
|
||||
public function update(Request $request, ServiceTemplate $template, ToastInterface $toast)
|
||||
{
|
||||
$this->validate(
|
||||
$request, [
|
||||
@@ -214,9 +214,9 @@ class ServiceTemplateController extends Controller
|
||||
if ($template->isDirty() || $devices_updated || isset($device_groups_updated)) {
|
||||
try {
|
||||
if ($template->save() || $devices_updated || isset($device_groups_updated)) {
|
||||
$flasher->addSuccess(__('Service Template :name updated', ['name' => $template->name]));
|
||||
$toast->success(__('Service Template :name updated', ['name' => $template->name]));
|
||||
} else {
|
||||
$flasher->addError(__('Failed to save'));
|
||||
$toast->error(__('Failed to save'));
|
||||
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
@@ -226,7 +226,7 @@ class ServiceTemplateController extends Controller
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$flasher->addInfo(__('No changes made'));
|
||||
$toast->info(__('No changes made'));
|
||||
}
|
||||
|
||||
return redirect()->route('services.templates.index');
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Interfaces\ToastInterface;
|
||||
use App\Http\Requests\StoreUserRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
use App\Models\AuthLog;
|
||||
@@ -32,7 +33,6 @@ use App\Models\Dashboard;
|
||||
use App\Models\User;
|
||||
use App\Models\UserPref;
|
||||
use Auth;
|
||||
use Flasher\Prime\FlasherInterface;
|
||||
use Illuminate\Support\Str;
|
||||
use LibreNMS\Authentication\LegacyAuth;
|
||||
use LibreNMS\Config;
|
||||
@@ -90,7 +90,7 @@ class UserController extends Controller
|
||||
* @param StoreUserRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreUserRequest $request, FlasherInterface $flasher)
|
||||
public function store(StoreUserRequest $request, ToastInterface $toast)
|
||||
{
|
||||
$user = $request->only(['username', 'realname', 'email', 'descr', 'can_modify_passwd']);
|
||||
$user['auth_type'] = LegacyAuth::getType();
|
||||
@@ -105,12 +105,12 @@ class UserController extends Controller
|
||||
$this->updateTimezone($user, $request->get('timezone'));
|
||||
|
||||
if ($user->save()) {
|
||||
$flasher->addSuccess(__('User :username created', ['username' => $user->username]));
|
||||
$toast->success(__('User :username created', ['username' => $user->username]));
|
||||
|
||||
return redirect(route('users.index'));
|
||||
}
|
||||
|
||||
$flasher->addError(__('Failed to create user'));
|
||||
$toast->error(__('Failed to create user'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
@@ -169,7 +169,7 @@ class UserController extends Controller
|
||||
* @param User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, User $user, FlasherInterface $flasher)
|
||||
public function update(UpdateUserRequest $request, User $user, ToastInterface $toast)
|
||||
{
|
||||
if ($request->get('new_password') && $user->canSetPassword($request->user())) {
|
||||
$user->setPassword($request->new_password);
|
||||
@@ -191,24 +191,24 @@ class UserController extends Controller
|
||||
}
|
||||
|
||||
if ($request->has('dashboard') && $this->updateDashboard($user, $request->get('dashboard'))) {
|
||||
$flasher->addSuccess(__('Updated dashboard for :username', ['username' => $user->username]));
|
||||
$toast->success(__('Updated dashboard for :username', ['username' => $user->username]));
|
||||
}
|
||||
|
||||
if ($request->has('timezone') && $this->updateTimezone($user, $request->get('timezone'))) {
|
||||
if ($request->get('timezone') != 'default') {
|
||||
$flasher->addSuccess(__('Updated timezone for :username', ['username' => $user->username]));
|
||||
$toast->success(__('Updated timezone for :username', ['username' => $user->username]));
|
||||
} else {
|
||||
$flasher->addSuccess(__('Cleared timezone for :username', ['username' => $user->username]));
|
||||
$toast->success(__('Cleared timezone for :username', ['username' => $user->username]));
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->save()) {
|
||||
$flasher->addSuccess(__('User :username updated', ['username' => $user->username]));
|
||||
$toast->success(__('User :username updated', ['username' => $user->username]));
|
||||
|
||||
return redirect(route(Str::contains(URL::previous(), 'preferences') ? 'preferences.index' : 'users.index'));
|
||||
}
|
||||
|
||||
$flasher->addError(__('Failed to update user :username', ['username' => $user->username]));
|
||||
$toast->error(__('Failed to update user :username', ['username' => $user->username]));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
70
app/Http/Interfaces/ToastInterface.php
Normal file
70
app/Http/Interfaces/ToastInterface.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* ToastInterface.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @link https://www.librenms.org
|
||||
*
|
||||
* @copyright 2024 Tony Murray
|
||||
* @author Tony Murray <murraytony@gmail.com>
|
||||
*/
|
||||
|
||||
namespace App\Http\Interfaces;
|
||||
|
||||
use Illuminate\Session\SessionManager;
|
||||
|
||||
class ToastInterface
|
||||
{
|
||||
public function __construct(
|
||||
private SessionManager $session
|
||||
) {
|
||||
}
|
||||
|
||||
public function info(string $title, ?string $message = null, ?array $options = null): static
|
||||
{
|
||||
return $this->message('info', $title, $message, $options);
|
||||
}
|
||||
|
||||
public function success(string $title, ?string $message = null, ?array $options = null): static
|
||||
{
|
||||
return $this->message('success', $title, $message, $options);
|
||||
}
|
||||
|
||||
public function error(string $title, ?string $message = null, ?array $options = null): static
|
||||
{
|
||||
return $this->message('error', $title, $message, $options);
|
||||
}
|
||||
|
||||
public function warning(string $title, ?string $message = null, ?array $options = null): static
|
||||
{
|
||||
return $this->message('warning', $title, $message, $options);
|
||||
}
|
||||
|
||||
public function message(string $level, string $title, ?string $message = null, ?array $options = null): static
|
||||
{
|
||||
$notifications = $this->session->get('toasts', []);
|
||||
array_push($notifications, [
|
||||
'level' => $level,
|
||||
'title' => $message === null ? '' : $title,
|
||||
'message' => $message ?? $title,
|
||||
'options' => $options ?? [],
|
||||
]);
|
||||
$this->session->flash('toasts', $notifications);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -33,7 +33,7 @@ class AuthEventListener
|
||||
|
||||
DB::table('authlog')->insert(['user' => $user->username ?: '', 'address' => Request::ip(), 'result' => 'Logged In']);
|
||||
|
||||
flash()->addInfo('Welcome ' . ($user->realname ?: $user->username));
|
||||
toast()->info('Welcome ' . ($user->realname ?: $user->username));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -136,7 +136,7 @@ class LegacyUserProvider implements UserProvider
|
||||
if (Debug::isEnabled()) {
|
||||
$auth_message .= '<br /> ' . $ae->getFile() . ': ' . $ae->getLine();
|
||||
}
|
||||
flash()->addError($auth_message);
|
||||
toast()->error($auth_message);
|
||||
|
||||
$username = $username ?? Session::get('username', $credentials['username']);
|
||||
|
||||
@@ -183,7 +183,7 @@ class LegacyUserProvider implements UserProvider
|
||||
|
||||
error_reporting(-1);
|
||||
} catch (AuthenticationException $ae) {
|
||||
flash()->addError($ae->getMessage());
|
||||
toast()->error($ae->getMessage());
|
||||
}
|
||||
|
||||
if (empty($new_user)) {
|
||||
|
36
app/View/Components/Toast.php
Normal file
36
app/View/Components/Toast.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Session\SessionManager;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Toast extends Component
|
||||
{
|
||||
public array $purifier_config = [
|
||||
'HTML.Allowed' => 'a[href],b,i,ul,ol,li,h1,h2,h3,h4,br,p,pre',
|
||||
'URI.DisableExternal' => true,
|
||||
];
|
||||
public ?array $toasts;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(Request $request, SessionManager $session)
|
||||
{
|
||||
$this->purifier_config['URI.Host'] = $request->getHttpHost();
|
||||
$this->toasts = $session->get('toasts');
|
||||
$session->forget('toasts'); // to ward againsts double toasts
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.toast');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user