From b57fd59e5b9abe769cac79837dff96868b6f38f8 Mon Sep 17 00:00:00 2001 From: Austin Kregel Date: Sun, 26 Jul 2020 23:02:22 -0400 Subject: [PATCH] Add bugsnag support for errors (#20) * Update composer dependencies and add bugsnag * Update config * Also make mysql storage persistant... * Update the channels some and the alerts modal. Still have to fix the listener to handle the newer data tho. * Finally figure out how we're going to support webhooks, slack, and discord. * Save the .env vars for how we handle slack/discord --- .env.example | 4 + .../GenerateChannelsAndAlertsFile.php | 34 +- .../Api/AbstractResourceController.php | 6 + .../Controllers/Api/AccountController.php | 4 +- app/Http/Controllers/Api/AlertController.php | 4 +- app/Http/Controllers/Api/TagController.php | 4 +- .../Controllers/Api/TransactionController.php | 5 +- app/Listeners/CreateDefaultAlertsForUser.php | 9 +- app/Notifications/AlertNotiffication.php | 9 +- composer.json | 1 + composer.lock | 312 ++++++++++++++---- config/app.php | 2 + config/logging.php | 6 +- config/services.php | 5 +- docker-compose.yml | 5 + resources/js/channels.js | 18 +- resources/js/components/AlertModal.vue | 61 +--- resources/js/state/Accounts.js | 2 +- resources/js/state/Authentication.js | 2 +- routes/web.php | 2 +- 20 files changed, 323 insertions(+), 172 deletions(-) diff --git a/.env.example b/.env.example index 4338bba3..02561325 100644 --- a/.env.example +++ b/.env.example @@ -42,3 +42,7 @@ PLAID_CLIENT_ID= MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +SLACK_WEBHOOK_URL= +DISCORD_WEBHOOK_URL= + diff --git a/app/Console/Commands/GenerateChannelsAndAlertsFile.php b/app/Console/Commands/GenerateChannelsAndAlertsFile.php index 113c0c47..a85ea754 100644 --- a/app/Console/Commands/GenerateChannelsAndAlertsFile.php +++ b/app/Console/Commands/GenerateChannelsAndAlertsFile.php @@ -34,54 +34,32 @@ class GenerateChannelsAndAlertsFile extends Command */ protected $description = 'Build channels and alerts.'; - /** - * Create a new command instance. - * - * @return void - */ - public function __construct() - { - parent::__construct(); - } - - /** - * Execute the console command. - * - * @return mixed - */ public function handle() { $this->writeToDisk('js/channels.js', [ [ - 'type' => SlackWebhookChannel::class, 'name' => 'Slack', - 'service' => 'webhook', + 'type' => SlackWebhookChannel::class, ], [ - 'type' => DiscordChannel::class, 'name' => 'Discord', - 'service' => 'webhook', + 'type' => DiscordChannel::class, ], [ - 'type' => WebhookChannel::class, 'name' => 'Webhook', - 'service' => 'webhook', + 'type' => WebhookChannel::class, ], [ - 'type' => MailChannel::class, 'name' => 'Email', - 'service' => 'email', + 'type' => MailChannel::class, ], [ - 'type' => NexmoSmsChannel::class, 'name' => 'Nexmo', - 'service' => 'sms' + 'type' => NexmoSmsChannel::class, ], [ - // BroadcastChannel::class - 'type' => DatabaseChannel::class, 'name' => 'In-site notification', - 'service' => 'in-site' + 'type' => DatabaseChannel::class, ], ]); diff --git a/app/Http/Controllers/Api/AbstractResourceController.php b/app/Http/Controllers/Api/AbstractResourceController.php index adfcf352..3f850695 100644 --- a/app/Http/Controllers/Api/AbstractResourceController.php +++ b/app/Http/Controllers/Api/AbstractResourceController.php @@ -2,7 +2,9 @@ namespace App\Http\Controllers\Api; +use App\FailedJob; use App\Http\Controllers\Controller; +use App\Models\Transaction; use Exception; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; @@ -37,6 +39,10 @@ public function index(IndexRequest $request, AbstractEloquentModel $model) ->allowedIncludes($model->getAbstractAllowedRelationships()) ->allowedSorts($model->getAbstractAllowedSorts()); + if (!in_array(get_class($model), [FailedJob::class, Transaction::class])) { + $query->where('user_id', auth()->id()); + } + return $this->json($action->execute($query)); } diff --git a/app/Http/Controllers/Api/AccountController.php b/app/Http/Controllers/Api/AccountController.php index 62d279cb..82554199 100644 --- a/app/Http/Controllers/Api/AccountController.php +++ b/app/Http/Controllers/Api/AccountController.php @@ -35,7 +35,8 @@ public function index(IndexRequest $request) Filter::scope('q') ])) ->allowedIncludes($model->getAbstractAllowedRelationships()) - ->allowedSorts($model->getAbstractAllowedSorts()); + ->allowedSorts($model->getAbstractAllowedSorts()) + ->whereIn('access_token_id', $request->user()->accessTokens->map->id); return $this->json($action->execute($query)); } @@ -56,6 +57,7 @@ public function show(ViewRequest $request, Account $model) ->allowedFilters($model->getAbstractAllowedFilters()) ->allowedIncludes($model->getAbstractAllowedRelationships()) ->allowedSorts($model->getAbstractAllowedSorts()) + ->whereIn('access_token_id', $request->user()->accessTokens->map->id) ->find($model->id); if (empty($result)) { diff --git a/app/Http/Controllers/Api/AlertController.php b/app/Http/Controllers/Api/AlertController.php index 97596136..6f29a4a3 100644 --- a/app/Http/Controllers/Api/AlertController.php +++ b/app/Http/Controllers/Api/AlertController.php @@ -31,7 +31,8 @@ public function index(IndexRequest $request) Filter::scope('q') ])) ->allowedIncludes($model->getAbstractAllowedRelationships()) - ->allowedSorts($model->getAbstractAllowedSorts()); + ->allowedSorts($model->getAbstractAllowedSorts()) + ->where('user_id', auth()->id()); return $this->json($action->execute($query)); } @@ -54,6 +55,7 @@ public function show(ViewRequest $request, Alert $model) ->allowedFilters($model->getAbstractAllowedFilters()) ->allowedIncludes($model->getAbstractAllowedRelationships()) ->allowedSorts($model->getAbstractAllowedSorts()) + ->where('user_id', auth()->id()) ->find($model->id); if (empty($result)) { diff --git a/app/Http/Controllers/Api/TagController.php b/app/Http/Controllers/Api/TagController.php index 1487a181..9fac2024 100644 --- a/app/Http/Controllers/Api/TagController.php +++ b/app/Http/Controllers/Api/TagController.php @@ -39,7 +39,8 @@ public function index(IndexRequest $request) Filter::scope('q') ])) ->allowedIncludes($model->getAbstractAllowedRelationships()) - ->allowedSorts($model->getAbstractAllowedSorts()); + ->allowedSorts($model->getAbstractAllowedSorts()) + ->where('user_id', auth()->id()); return $this->json($action->execute($query)); } @@ -63,6 +64,7 @@ public function show(ViewRequest $request, Tag $model) ->allowedFilters($model->getAbstractAllowedFilters()) ->allowedIncludes($model->getAbstractAllowedRelationships()) ->allowedSorts($model->getAbstractAllowedSorts()) + ->where('user_id', auth()->id()) ->find($model->id); if (empty($result)) { diff --git a/app/Http/Controllers/Api/TransactionController.php b/app/Http/Controllers/Api/TransactionController.php index 0bfceaf8..b092908b 100644 --- a/app/Http/Controllers/Api/TransactionController.php +++ b/app/Http/Controllers/Api/TransactionController.php @@ -37,7 +37,10 @@ public function index(IndexRequest $request) Filter::scope('q') ])) ->allowedIncludes($model->getAbstractAllowedRelationships()) - ->allowedSorts($model->getAbstractAllowedSorts()); + ->allowedSorts($model->getAbstractAllowedSorts()) + ->whereHas('account', function ($query) use ($request) { + $query->whereIn('access_token_id', $request->user()->accessTokens->map->id); + }); return $this->json($action->execute($query)); } diff --git a/app/Listeners/CreateDefaultAlertsForUser.php b/app/Listeners/CreateDefaultAlertsForUser.php index 142e155c..ae4af88a 100644 --- a/app/Listeners/CreateDefaultAlertsForUser.php +++ b/app/Listeners/CreateDefaultAlertsForUser.php @@ -30,12 +30,13 @@ class CreateDefaultAlertsForUser TransactionCreated::class, ], 'channels' => [ + MailChannel::class, DatabaseChannel::class, ] ], [ 'name' => 'Bill paid!', - 'title' => 'You just paid your {{ transaction.name }} {{ tag.name }}!', + 'title' => 'You just paid your {{ transaction.name }} {{ tag.name.en }}!', 'body' => 'This time around, you paid ${{ transaction.amount }}.', 'conditions' => [ [ @@ -53,7 +54,7 @@ class CreateDefaultAlertsForUser ], [ 'name' => 'Subscription paid!', - 'title' => 'You just paid your {{ transaction.name }} {{ tag.name }}!', + 'title' => 'You just paid your {{ transaction.name }} {{ tag.name.en }}!', 'body' => 'This time around, you paid ${{ transaction.amount }}.', 'conditions' => [ [ @@ -93,6 +94,10 @@ public function handle(Registered $event) $conditions = $alertInfo['conditions']; unset($alertInfo['conditions']); + if (isset($alertInfo['channels'][MailChannel::class]) && isset($alertInfo['channels'][MailChannel::class]['fields']['to'])) { + $alertInfo['channels'][MailChannel::class]['fields']['to'] = $user->email; + } + /** @var Alert $alert */ $alert = $user->alerts()->create($alertInfo); foreach ($conditions as $condition) { diff --git a/app/Notifications/AlertNotiffication.php b/app/Notifications/AlertNotiffication.php index 39614f95..41ea704d 100644 --- a/app/Notifications/AlertNotiffication.php +++ b/app/Notifications/AlertNotiffication.php @@ -59,12 +59,12 @@ protected function render($string, $data) public function routeNotificationForDiscord() { - return $this->alertLog->alert->messaging_service_channel; + return config('services.discord_webhook_url'); } public function routeNotificationForSlack($notification) { - return $this->alertLog->alert->webhook_url; + return config('services.slack_webhook_url'); } public function toMail($notifiable) @@ -80,9 +80,10 @@ public function toSlack($notifiable) ->warning(); } - public function toDiscord() + public function toDiscord($notifiable) { - return new DiscordMessage(sprintf('We saw you were charged $%s by %s to your account %s', $this->alertLog->transaction->amount, $this->alertLog->transaction->name, $this->alertLog->transaction->account->name)); + return (new DiscordMessage) + ->body(sprintf('We saw you were charged $%s by %s to your account %s', $this->alertLog->transaction->amount, $this->alertLog->transaction->name, $this->alertLog->transaction->account->name)); } public function toWebhook($notifiable) diff --git a/composer.json b/composer.json index 778cf0a1..0869e74b 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "require": { "php": "^7.4", "barryvdh/laravel-debugbar": "^3.3", + "bugsnag/bugsnag-laravel": "^2.0", "doctrine/dbal": "^2.9", "fideloper/proxy": "^4.2", "firebase/php-jwt": "^5.0", diff --git a/composer.lock b/composer.lock index 738b99c8..10af42e1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "75ec37e7995c18e1b4296a9a9c34c4e8", + "content-hash": "03c8d220d937592cfe5f1197f7d5f69f", "packages": [ { "name": "asm89/stack-cors", @@ -184,6 +184,184 @@ ], "time": "2020-04-15T15:59:35+00:00" }, + { + "name": "bugsnag/bugsnag", + "version": "v3.21.0", + "source": { + "type": "git", + "url": "https://github.com/bugsnag/bugsnag-php.git", + "reference": "531fe1c16beb68af698e35bd5b3a19a422399e28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bugsnag/bugsnag-php/zipball/531fe1c16beb68af698e35bd5b3a19a422399e28", + "reference": "531fe1c16beb68af698e35bd5b3a19a422399e28", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "guzzlehttp/guzzle": "^5.0|^6.0|^7.0", + "php": ">=5.5" + }, + "require-dev": { + "graham-campbell/testbench-core": "^1.1", + "guzzlehttp/psr7": "^1.3", + "mockery/mockery": "^0.9.4|^1.3.1", + "mtdowling/burgomaster": "dev-master#72151eddf5f0cf101502b94bf5031f9c53501a04", + "php-mock/php-mock-phpunit": "^1.1|^2.1", + "phpunit/phpunit": "^4.8.36|^7.5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.20-dev" + } + }, + "autoload": { + "psr-4": { + "Bugsnag\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Smith", + "email": "notifiers@bugsnag.com", + "homepage": "https://bugsnag.com" + } + ], + "description": "Official Bugsnag notifier for PHP applications.", + "homepage": "https://github.com/bugsnag/bugsnag-php", + "keywords": [ + "bugsnag", + "errors", + "exceptions", + "logging", + "tracking" + ], + "time": "2020-04-29T10:59:17+00:00" + }, + { + "name": "bugsnag/bugsnag-laravel", + "version": "v2.19.0", + "source": { + "type": "git", + "url": "https://github.com/bugsnag/bugsnag-laravel.git", + "reference": "bebac599024d76210b9a5172372263e7ec6db9c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bugsnag/bugsnag-laravel/zipball/bebac599024d76210b9a5172372263e7ec6db9c2", + "reference": "bebac599024d76210b9a5172372263e7ec6db9c2", + "shasum": "" + }, + "require": { + "bugsnag/bugsnag": "^3.20", + "bugsnag/bugsnag-psr-logger": "^1.4", + "illuminate/contracts": "^5.0|^6.0|^7.0", + "illuminate/support": "^5.0|^6.0|^7.0", + "monolog/monolog": "^1.12|^2.0", + "php": ">=5.5" + }, + "require-dev": { + "graham-campbell/testbench": "^3.1|^4.0|^5.0", + "mockery/mockery": "^0.9.4|^1.3.1", + "phpunit/phpunit": "^4.8.36|^5.6.3|^6.3.1|^7.5.15|^8.3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.18-dev" + } + }, + "autoload": { + "psr-4": { + "Bugsnag\\BugsnagLaravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Smith", + "email": "notifiers@bugsnag.com" + } + ], + "description": "Official Bugsnag notifier for Laravel applications.", + "homepage": "https://github.com/bugsnag/bugsnag-laravel", + "keywords": [ + "bugsnag", + "errors", + "exceptions", + "laravel", + "logging", + "tracking" + ], + "time": "2020-05-11T09:33:48+00:00" + }, + { + "name": "bugsnag/bugsnag-psr-logger", + "version": "v1.4.3", + "source": { + "type": "git", + "url": "https://github.com/bugsnag/bugsnag-psr-logger.git", + "reference": "222a7338bc5c39833c7c3922a175c539e996797c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bugsnag/bugsnag-psr-logger/zipball/222a7338bc5c39833c7c3922a175c539e996797c", + "reference": "222a7338bc5c39833c7c3922a175c539e996797c", + "shasum": "" + }, + "require": { + "bugsnag/bugsnag": "^3.10", + "php": ">=5.5", + "psr/log": "^1.0" + }, + "require-dev": { + "graham-campbell/testbench-core": "^1.1", + "mockery/mockery": "^0.9.4|^1.3.1", + "phpunit/phpunit": "^4.8.36|^7.5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "psr-4": { + "Bugsnag\\PsrLogger\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Smith", + "email": "notifiers@bugsnag.com", + "homepage": "https://bugsnag.com" + } + ], + "description": "Official Bugsnag PHP PSR Logger.", + "homepage": "https://github.com/bugsnag/bugsnag-psr", + "keywords": [ + "bugsnag", + "errors", + "exceptions", + "logging", + "psr", + "tracking" + ], + "time": "2020-02-26T22:02:20+00:00" + }, { "name": "cakephp/chronos", "version": "2.0.5", @@ -239,6 +417,72 @@ ], "time": "2020-05-26T01:27:20+00:00" }, + { + "name": "composer/ca-bundle", + "version": "1.2.7", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/95c63ab2117a72f48f5a55da9740a3273d45b7fd", + "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-04-08T08:27:21+00:00" + }, { "name": "dnoegel/php-xdg-base-dir", "version": "v0.1.1", @@ -6793,72 +7037,6 @@ ], "time": "2020-03-04T15:23:26+00:00" }, - { - "name": "composer/ca-bundle", - "version": "1.2.7", - "source": { - "type": "git", - "url": "https://github.com/composer/ca-bundle.git", - "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/95c63ab2117a72f48f5a55da9740a3273d45b7fd", - "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd", - "shasum": "" - }, - "require": { - "ext-openssl": "*", - "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8", - "psr/log": "^1.0", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\CaBundle\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", - "keywords": [ - "cabundle", - "cacert", - "certificate", - "ssl", - "tls" - ], - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2020-04-08T08:27:21+00:00" - }, { "name": "composer/composer", "version": "1.10.8", diff --git a/config/app.php b/config/app.php index 0f522d01..986f55f8 100644 --- a/config/app.php +++ b/config/app.php @@ -164,6 +164,8 @@ Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + Bugsnag\BugsnagLaravel\BugsnagServiceProvider::class, + /* * Application Service Providers... */ diff --git a/config/logging.php b/config/logging.php index d09cd7d2..909570a4 100644 --- a/config/logging.php +++ b/config/logging.php @@ -36,7 +36,7 @@ 'channels' => [ 'stack' => [ 'driver' => 'stack', - 'channels' => ['daily'], + 'channels' => ['single', 'bugsnag'], 'ignore_exceptions' => false, ], @@ -89,6 +89,10 @@ 'driver' => 'errorlog', 'level' => 'debug', ], + + 'bugsnag' => [ + 'driver' => 'bugsnag', + ] ], ]; diff --git a/config/services.php b/config/services.php index ede58a1b..69f28d93 100644 --- a/config/services.php +++ b/config/services.php @@ -49,5 +49,8 @@ 'public_key' => env('PLAID_PUBLIC_KEY', ''), 'secret_key' => env('PLAID_SECRET', ''), 'client_id' => env('PLAID_CLIENT_ID', '') - ] + ], + + 'slack_webhook_url' => env('SLACK_WEBHOOK_URL'), + 'discord_webhook_url' => env('DISCORD_WEBHOOK_URL'), ]; diff --git a/docker-compose.yml b/docker-compose.yml index 6da1066a..999fa3b0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,9 @@ services: MYSQL_ROOT_PASSWORD: secret networks: - code-network + volumes: + - mysql-data:/var/lib/mysql + redis: container_name: finance-redis image: redis:4.0-alpine @@ -54,3 +57,5 @@ services: networks: code-network: driver: bridge +volumes: + mysql-data: diff --git a/resources/js/channels.js b/resources/js/channels.js index 9c3f859f..b812d52a 100644 --- a/resources/js/channels.js +++ b/resources/js/channels.js @@ -1,32 +1,26 @@ module.exports = [ { - "type": "Illuminate\\Notifications\\Channels\\SlackWebhookChannel", "name": "Slack", - "service": "webhook" + "type": "Illuminate\\Notifications\\Channels\\SlackWebhookChannel" }, { - "type": "NotificationChannels\\Discord\\DiscordChannel", "name": "Discord", - "service": "webhook" + "type": "NotificationChannels\\Discord\\DiscordChannel" }, { - "type": "NotificationChannels\\Webhook\\WebhookChannel", "name": "Webhook", - "service": "webhook" + "type": "NotificationChannels\\Webhook\\WebhookChannel" }, { - "type": "Illuminate\\Notifications\\Channels\\MailChannel", "name": "Email", - "service": "email" + "type": "Illuminate\\Notifications\\Channels\\MailChannel" }, { - "type": "Illuminate\\Notifications\\Channels\\NexmoSmsChannel", "name": "Nexmo", - "service": "sms" + "type": "Illuminate\\Notifications\\Channels\\NexmoSmsChannel" }, { - "type": "Illuminate\\Notifications\\Channels\\DatabaseChannel", "name": "In-site notification", - "service": "in-site" + "type": "Illuminate\\Notifications\\Channels\\DatabaseChannel" } ] \ No newline at end of file diff --git a/resources/js/components/AlertModal.vue b/resources/js/components/AlertModal.vue index 7e1b0957..ec75a911 100644 --- a/resources/js/components/AlertModal.vue +++ b/resources/js/components/AlertModal.vue @@ -84,60 +84,20 @@ -