This commit is contained in:
Andras Bacsai 2023-07-28 10:55:26 +02:00
parent e9bd1f88c0
commit 7e4b1a8f8f
30 changed files with 198 additions and 95 deletions

View File

@ -4,7 +4,7 @@ namespace App\Http\Livewire\Application;
use App\Jobs\ApplicationContainerStatusJob; use App\Jobs\ApplicationContainerStatusJob;
use App\Models\Application; use App\Models\Application;
use App\Notifications\Notifications\Application\ApplicationStoppedNotification; use App\Notifications\Application\StatusChanged;
use Livewire\Component; use Livewire\Component;
use Visus\Cuid2\Cuid2; use Visus\Cuid2\Cuid2;
@ -55,7 +55,7 @@ class Heading extends Component
); );
$this->application->status = 'stopped'; $this->application->status = 'stopped';
$this->application->save(); $this->application->save();
$this->application->environment->project->team->notify(new ApplicationStoppedNotification($this->application)); $this->application->environment->project->team->notify(new StatusChanged($this->application));
} }
protected function setDeploymentUuid() protected function setDeploymentUuid()
{ {

View File

@ -3,7 +3,7 @@
namespace App\Http\Livewire\Notifications; namespace App\Http\Livewire\Notifications;
use App\Models\Team; use App\Models\Team;
use App\Notifications\Notifications\TestNotification; use App\Notifications\Test;
use Livewire\Component; use Livewire\Component;
class DiscordSettings extends Component class DiscordSettings extends Component
@ -46,7 +46,7 @@ class DiscordSettings extends Component
} }
public function sendTestNotification() public function sendTestNotification()
{ {
$this->model->notify(new TestNotification('discord')); $this->model->notify(new Test);
$this->emit('success', 'Test notification sent.'); $this->emit('success', 'Test notification sent.');
} }
} }

View File

@ -4,12 +4,13 @@ namespace App\Http\Livewire\Notifications;
use App\Models\InstanceSettings; use App\Models\InstanceSettings;
use App\Models\Team; use App\Models\Team;
use App\Notifications\Notifications\TestNotification; use App\Notifications\Test;
use Livewire\Component; use Livewire\Component;
class EmailSettings extends Component class EmailSettings extends Component
{ {
public Team $model; public Team $model;
public string $emails;
protected $rules = [ protected $rules = [
'model.smtp_enabled' => 'nullable|boolean', 'model.smtp_enabled' => 'nullable|boolean',
@ -48,6 +49,7 @@ class EmailSettings extends Component
public function mount() public function mount()
{ {
$this->decrypt(); $this->decrypt();
$this->emails = auth()->user()->email;
} }
public function copyFromInstanceSettings() public function copyFromInstanceSettings()
{ {
@ -93,8 +95,8 @@ class EmailSettings extends Component
} }
public function sendTestNotification() public function sendTestNotification()
{ {
$this->model->notify(new TestNotification('smtp')); $this->model->notify(new Test($this->emails));
$this->emit('success', 'Test notification sent.'); $this->emit('success', 'Test Email sent successfully.');
} }
public function instantSave() public function instantSave()
{ {

View File

@ -3,14 +3,14 @@
namespace App\Http\Livewire\Settings; namespace App\Http\Livewire\Settings;
use App\Models\InstanceSettings; use App\Models\InstanceSettings;
use App\Notifications\TransactionalEmails\TestEmail; use App\Notifications\TransactionalEmails\Test;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
use Livewire\Component; use Livewire\Component;
class Email extends Component class Email extends Component
{ {
public InstanceSettings $settings; public InstanceSettings $settings;
public string $emails;
protected $rules = [ protected $rules = [
'settings.smtp_enabled' => 'nullable|boolean', 'settings.smtp_enabled' => 'nullable|boolean',
'settings.smtp_host' => 'required', 'settings.smtp_host' => 'required',
@ -35,6 +35,7 @@ class Email extends Component
public function mount() public function mount()
{ {
$this->decrypt(); $this->decrypt();
$this->emails = auth()->user()->email;
} }
public function instantSave() public function instantSave()
{ {
@ -46,9 +47,9 @@ class Email extends Component
$this->validate(); $this->validate();
} }
} }
public function testNotification() public function sendTestNotification()
{ {
$this->settings->notify(new TestEmail); $this->settings->notify(new Test($this->emails));
$this->emit('success', 'Test email sent.'); $this->emit('success', 'Test email sent.');
} }
private function decrypt() private function decrypt()

View File

@ -4,7 +4,7 @@ namespace App\Http\Livewire\Team;
use App\Models\TeamInvitation; use App\Models\TeamInvitation;
use App\Models\User; use App\Models\User;
use App\Notifications\TransactionalEmails\InvitationLinkEmail; use App\Notifications\TransactionalEmails\InvitationLink;
use Livewire\Component; use Livewire\Component;
use Visus\Cuid2\Cuid2; use Visus\Cuid2\Cuid2;
@ -58,7 +58,7 @@ class InviteLink extends Component
'via' => $isEmail ? 'email' : 'link', 'via' => $isEmail ? 'email' : 'link',
]); ]);
if ($isEmail) { if ($isEmail) {
$user->first()->notify(new InvitationLinkEmail()); $user->first()->notify(new InvitationLink);
$this->emit('success', 'Invitation sent via email successfully.'); $this->emit('success', 'Invitation sent via email successfully.');
} else { } else {
$this->emit('success', 'Invitation link generated.'); $this->emit('success', 'Invitation link generated.');

View File

@ -4,7 +4,7 @@ namespace App\Jobs;
use App\Models\Application; use App\Models\Application;
use App\Models\ApplicationPreview; use App\Models\ApplicationPreview;
use App\Notifications\Notifications\Application\ApplicationStoppedNotification; use App\Notifications\Application\StatusChanged;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
@ -36,7 +36,7 @@ class ApplicationContainerStatusJob implements ShouldQueue, ShouldBeUnique
try { try {
$status = get_container_status(server: $this->application->destination->server, container_id: $this->container_name, throwError: false); $status = get_container_status(server: $this->application->destination->server, container_id: $this->container_name, throwError: false);
if ($this->application->status === 'running' && $status === 'stopped') { if ($this->application->status === 'running' && $status === 'stopped') {
$this->application->environment->project->team->notify(new ApplicationStoppedNotification($this->application)); $this->application->environment->project->team->notify(new StatusChanged($this->application));
} }
if ($this->pull_request_id) { if ($this->pull_request_id) {

View File

@ -12,8 +12,8 @@ use App\Models\GitlabApp;
use App\Models\Server; use App\Models\Server;
use App\Models\StandaloneDocker; use App\Models\StandaloneDocker;
use App\Models\SwarmDocker; use App\Models\SwarmDocker;
use App\Notifications\Notifications\Application\DeployedSuccessfullyNotification; use App\Notifications\Application\DeploymentSuccess;
use App\Notifications\Notifications\Application\DeployedWithErrorNotification; use App\Notifications\Application\DeploymentFailed;
use App\Traits\ExecuteRemoteCommand; use App\Traits\ExecuteRemoteCommand;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
@ -224,10 +224,10 @@ class ApplicationDeploymentJob implements ShouldQueue
} }
queue_next_deployment($this->application); queue_next_deployment($this->application);
if ($status === ApplicationDeploymentStatus::FINISHED->value) { if ($status === ApplicationDeploymentStatus::FINISHED->value) {
$this->application->environment->project->team->notify(new DeployedSuccessfullyNotification($this->application, $this->deployment_uuid, $this->preview)); $this->application->environment->project->team->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
} }
if ($status === ApplicationDeploymentStatus::FAILED->value) { if ($status === ApplicationDeploymentStatus::FAILED->value) {
$this->application->environment->project->team->notify(new DeployedWithErrorNotification($this->application, $this->deployment_uuid, $this->preview)); $this->application->environment->project->team->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview));
} }
} }
private function start_by_compose_file() private function start_by_compose_file()

View File

@ -15,9 +15,9 @@ class InstanceSettings extends Model implements SendsEmail
protected $casts = [ protected $casts = [
'resale_license' => 'encrypted', 'resale_license' => 'encrypted',
]; ];
public function routeNotificationForEmail(string $attribute = 'test_recipients') public function getRecepients($notification)
{ {
$recipients = data_get($this,'smtp',''); $recipients = data_get($notification,'emails',null);
if (is_null($recipients) || $recipients === '') { if (is_null($recipients) || $recipients === '') {
return []; return [];
} }

View File

@ -23,11 +23,14 @@ class Team extends Model implements SendsDiscord, SendsEmail
{ {
return data_get($this, 'discord_webhook_url', null); return data_get($this, 'discord_webhook_url', null);
} }
public function routeNotificationForEmail(string $attribute = 'recipients') public function getRecepients($notification)
{ {
$recipients = data_get($this, 'smtp_recipients', ''); $recipients = data_get($notification,'emails',null);
if (is_null($recipients) || $recipients === '') { ray($recipients);
return []; if (is_null($recipients)) {
$recipients = $this->members()->pluck('email')->toArray();
ray($recipients);
return $recipients;
} }
return explode(',', $recipients); return explode(',', $recipients);
} }

View File

@ -10,6 +10,7 @@ use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; use Laravel\Sanctum\HasApiTokens;
use Visus\Cuid2\Cuid2; use Visus\Cuid2\Cuid2;
use Laravel\Fortify\TwoFactorAuthenticatable; use Laravel\Fortify\TwoFactorAuthenticatable;
use App\Notifications\TrnsactionalEmails\ResetPassword;
class User extends Authenticatable implements SendsEmail class User extends Authenticatable implements SendsEmail
{ {
@ -43,10 +44,14 @@ class User extends Authenticatable implements SendsEmail
$user->teams()->attach($new_team, ['role' => 'owner']); $user->teams()->attach($new_team, ['role' => 'owner']);
}); });
} }
public function routeNotificationForEmail() public function getRecepients($notification)
{ {
return $this->email; return $this->email;
} }
public function sendPasswordResetNotification($token): void
{
$this->notify(new ResetPassword($token));
}
public function isAdmin() public function isAdmin()
{ {
return $this->pivot->role === 'admin' || $this->pivot->role === 'owner'; return $this->pivot->role === 'admin' || $this->pivot->role === 'owner';

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Notifications\Notifications\Application; namespace App\Notifications\Application;
use App\Models\Application; use App\Models\Application;
use App\Models\ApplicationPreview; use App\Models\ApplicationPreview;
@ -13,7 +13,7 @@ use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class DeployedWithErrorNotification extends Notification implements ShouldQueue class DeploymentFailed extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public Application $application; public Application $application;
@ -69,7 +69,7 @@ class DeployedWithErrorNotification extends Notification implements ShouldQueue
$mail->subject('❌ Pull request #' . $this->preview->pull_request_id . ' of ' . $this->application_name . ' deployment failed.'); $mail->subject('❌ Pull request #' . $this->preview->pull_request_id . ' of ' . $this->application_name . ' deployment failed.');
} }
$mail->view('emails.application-deployed-with-error', [ $mail->view('emails.application-deployment-failed', [
'name' => $this->application_name, 'name' => $this->application_name,
'fqdn' => $fqdn, 'fqdn' => $fqdn,
'deployment_url' => $this->deployment_url, 'deployment_url' => $this->deployment_url,

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Notifications\Notifications\Application; namespace App\Notifications\Application;
use App\Models\Application; use App\Models\Application;
use App\Models\ApplicationPreview; use App\Models\ApplicationPreview;
@ -13,7 +13,7 @@ use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class DeployedSuccessfullyNotification extends Notification implements ShouldQueue class DeploymentSuccess extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public Application $application; public Application $application;
@ -67,7 +67,7 @@ class DeployedSuccessfullyNotification extends Notification implements ShouldQue
$fqdn = $this->preview->fqdn; $fqdn = $this->preview->fqdn;
$mail->subject("✅ Pull request #{$pull_request_id} of {$this->application_name} deployed successfully"); $mail->subject("✅ Pull request #{$pull_request_id} of {$this->application_name} deployed successfully");
} }
$mail->view('emails.application-deployed-successfully', [ $mail->view('emails.application-deployment-success', [
'name' => $this->application_name, 'name' => $this->application_name,
'fqdn' => $fqdn, 'fqdn' => $fqdn,
'deployment_url' => $this->deployment_url, 'deployment_url' => $this->deployment_url,

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Notifications\Notifications\Application; namespace App\Notifications\Application;
use App\Models\Application; use App\Models\Application;
use App\Models\ApplicationPreview; use App\Models\ApplicationPreview;
@ -12,7 +12,7 @@ use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class ApplicationStoppedNotification extends Notification implements ShouldQueue class StatusChanged extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public Application $application; public Application $application;
@ -56,7 +56,7 @@ class ApplicationStoppedNotification extends Notification implements ShouldQueue
$mail = new MailMessage(); $mail = new MailMessage();
$fqdn = $this->fqdn; $fqdn = $this->fqdn;
$mail->subject("{$this->application_name} has been stopped"); $mail->subject("{$this->application_name} has been stopped");
$mail->view('emails.application-stopped', [ $mail->view('emails.application-status-changes', [
'name' => $this->application_name, 'name' => $this->application_name,
'fqdn' => $fqdn, 'fqdn' => $fqdn,
'application_url' => $this->application_url, 'application_url' => $this->application_url,

View File

@ -11,13 +11,13 @@ class EmailChannel
public function send(SendsEmail $notifiable, Notification $notification): void public function send(SendsEmail $notifiable, Notification $notification): void
{ {
$this->bootConfigs($notifiable); $this->bootConfigs($notifiable);
ray($notification);
$recepients = $notifiable->getRecepients($notification);
$bcc = $notifiable->routeNotificationForEmail('test_recipients'); if (count($recepients) === 0) {
if (count($bcc) === 0) { throw new \Exception('No email recipients found');
if ($notifiable instanceof \App\Models\Team) {
$bcc = $notifiable->members()->pluck('email')->toArray();
}
} }
$mailMessage = $notification->toMail($notifiable); $mailMessage = $notification->toMail($notifiable);
Mail::send( Mail::send(
[], [],
@ -27,7 +27,7 @@ class EmailChannel
data_get($notifiable, 'smtp_from_address'), data_get($notifiable, 'smtp_from_address'),
data_get($notifiable, 'smtp_from_name'), data_get($notifiable, 'smtp_from_name'),
) )
->bcc($bcc) ->bcc($recepients)
->subject($mailMessage->subject) ->subject($mailMessage->subject)
->html((string)$mailMessage->render()) ->html((string)$mailMessage->render())
); );

View File

@ -4,5 +4,5 @@ namespace App\Notifications\Channels;
interface SendsEmail interface SendsEmail
{ {
public function routeNotificationForEmail(); public function getRecepients($notification);
} }

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Notifications\Notifications; namespace App\Notifications;
use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\DiscordChannel;
@ -9,30 +9,25 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
class TestNotification extends Notification implements ShouldQueue class Test extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public string|null $type = null; public function __construct(public string|null $emails = null)
public function __construct(string|null $type = null) {}
{
$this->type = $type;
}
public function via(object $notifiable): array public function via(object $notifiable): array
{ {
$channels = []; $channels = [];
$isSmtp = $this->type === 'smtp' || is_null($this->type);
$isDiscord = $this->type === 'discord' || is_null($this->type);
$isEmailEnabled = data_get($notifiable, 'smtp_enabled'); $isEmailEnabled = data_get($notifiable, 'smtp_enabled');
$isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isDiscordEnabled = data_get($notifiable, 'discord_enabled');
if ($isEmailEnabled && $isSmtp) { if ($isDiscordEnabled && empty($this->emails)) {
$channels[] = EmailChannel::class;
}
if ($isDiscordEnabled && $isDiscord) {
$channels[] = DiscordChannel::class; $channels[] = DiscordChannel::class;
} }
if ($isEmailEnabled && !empty($this->emails)) {
$channels[] = EmailChannel::class;
}
return $channels; return $channels;
} }
public function toMail(): MailMessage public function toMail(): MailMessage
@ -42,7 +37,6 @@ class TestNotification extends Notification implements ShouldQueue
$mail->view('emails.test'); $mail->view('emails.test');
return $mail; return $mail;
} }
public function toDiscord(): string public function toDiscord(): string
{ {
$message = 'This is a test Discord notification from Coolify.'; $message = 'This is a test Discord notification from Coolify.';

View File

@ -11,7 +11,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
class InvitationLinkEmail extends Notification implements ShouldQueue class InvitationLink extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public function via() public function via()

View File

@ -0,0 +1,83 @@
<?php
namespace App\Notifications\TransactionalEmails;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
use App\Models\InstanceSettings;
class ResetPassword extends Notification
{
public $token;
public InstanceSettings $settings;
public static $createUrlCallback;
public static $toMailCallback;
public function __construct($token)
{
$this->settings = InstanceSettings::get();
$this->token = $token;
}
public function via($notifiable)
{
if ($this->settings->smtp_enabled){
$password = data_get($this->settings, 'smtp_password');
if ($password) $password = decrypt($password);
config()->set('mail.default', 'smtp');
config()->set('mail.mailers.smtp', [
"transport" => "smtp",
"host" => data_get($this->settings, 'smtp_host'),
"port" => data_get($this->settings, 'smtp_port'),
"encryption" => data_get($this->settings, 'smtp_encryption'),
"username" => data_get($this->settings, 'smtp_username'),
"password" => $password,
"timeout" => data_get($this->settings, 'smtp_timeout'),
"local_domain" => null,
]);
return ['mail'];
}
throw new \Exception('SMTP is not enabled');
}
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return $this->buildMailMessage($this->resetUrl($notifiable));
}
protected function buildMailMessage($url)
{
$mail = new MailMessage();
$mail->from(
data_get($this->settings, 'smtp_from_address'),
data_get($this->settings, 'smtp_from_name'),
);
$mail->subject('Reset Password');
$mail->view('emails.reset-password', ['url' => $url,'count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]);
return $mail;
}
protected function resetUrl($notifiable)
{
if (static::$createUrlCallback) {
return call_user_func(static::$createUrlCallback, $notifiable, $this->token);
}
return url(route('password.reset', [
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
}
public static function createUrlUsing($callback)
{
static::$createUrlCallback = $callback;
}
public static function toMailUsing($callback)
{
static::$toMailCallback = $callback;
}
}

View File

@ -8,13 +8,18 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
class TestEmail extends Notification implements ShouldQueue class Test extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public function __construct(public string $emails)
{}
public function via(): array public function via(): array
{ {
return [EmailChannel::class]; return [EmailChannel::class];
} }
public function toMail(): MailMessage public function toMail(): MailMessage
{ {
$mail = new MailMessage(); $mail = new MailMessage();

View File

@ -30,7 +30,7 @@ class Input extends Component
if (is_null($this->id)) $this->id = new Cuid2(7); if (is_null($this->id)) $this->id = new Cuid2(7);
if (is_null($this->name)) $this->name = $this->id; if (is_null($this->name)) $this->name = $this->id;
$this->label = Str::title($this->label); // $this->label = Str::title($this->label);
return view('components.forms.input'); return view('components.forms.input');
} }
} }

View File

@ -0,0 +1,2 @@
{{ $name }} has been stopped.<br><br>
<a target="_blank" href="{{ $application_url }}">Open in Coolify</a><br><br>

View File

@ -1,2 +0,0 @@
{{ $name }} has been stopped.<br><br>
<a target="_blank" href="{{ $application_url }}">View Application URL</a><br><br>

View File

@ -2,4 +2,7 @@ Hello,<br><br>
A password reset requested for your email address on "{{ config('app.name') }}".<br><br> A password reset requested for your email address on "{{ config('app.name') }}".<br><br>
Please click the following link to reset your password: <a target="_blank" href="{{ $url }}">Password Reset</a> Please click the following link to reset your password: <a target="_blank" href="{{ $url }}">Password
Reset</a><br><br>
This password reset link will expire in "{{ $count }}" minutes.

View File

@ -23,12 +23,11 @@
<h4 class="mt-4">Subscribe to events</h4> <h4 class="mt-4">Subscribe to events</h4>
<div class="w-64 "> <div class="w-64 ">
@if (isDev()) @if (isDev())
<x-forms.checkbox instantSave="saveModel" id="model.discord_notifications_test" <x-forms.checkbox instantSave="saveModel" id="model.discord_notifications_test" label="Test" />
label="Test Notifications" />
@endif @endif
<h5 class="mt-4">Applications</h5> <h5 class="mt-4">Applications</h5>
<x-forms.checkbox instantSave="saveModel" id="model.discord_notifications_deployments" <x-forms.checkbox instantSave="saveModel" id="model.discord_notifications_deployments"
label="New Deployment" /> label="Deployments" />
<x-forms.checkbox instantSave="saveModel" id="model.discord_notifications_status_changes" <x-forms.checkbox instantSave="saveModel" id="model.discord_notifications_status_changes"
label="Status Changes" /> label="Status Changes" />
</div> </div>

View File

@ -3,7 +3,7 @@
<form method="dialog" class="flex flex-col gap-2 rounded modal-box" wire:submit.prevent='submit'> <form method="dialog" class="flex flex-col gap-2 rounded modal-box" wire:submit.prevent='submit'>
<x-forms.input placeholder="test@example.com" id="emails" label="Recepients" required /> <x-forms.input placeholder="test@example.com" id="emails" label="Recepients" required />
<x-forms.button onclick="sendTestEmail.close()" wire:click="sendTestNotification"> <x-forms.button onclick="sendTestEmail.close()" wire:click="sendTestNotification">
Send Test Emails Send Email
</x-forms.button> </x-forms.button>
</form> </form>
<form method="dialog" class="modal-backdrop"> <form method="dialog" class="modal-backdrop">
@ -44,8 +44,8 @@
label="Encryption" /> label="Encryption" />
</div> </div>
<div class="flex flex-col gap-2 xl:flex-row"> <div class="flex flex-col gap-2 xl:flex-row">
<x-forms.input id="model.smtp_username" helper="SMTP Username" label="SMTP Username" /> <x-forms.input id="model.smtp_username" label="SMTP Username" />
<x-forms.input type="password" helper="SMTP Password" id="model.smtp_password" label="SMTP Password" /> <x-forms.input type="password" id="model.smtp_password" label="SMTP Password" />
<x-forms.input id="model.smtp_timeout" helper="Timeout value for sending emails." label="Timeout" /> <x-forms.input id="model.smtp_timeout" helper="Timeout value for sending emails." label="Timeout" />
</div> </div>
<div class="flex flex-col gap-2 xl:flex-row"> <div class="flex flex-col gap-2 xl:flex-row">
@ -58,12 +58,10 @@
<h4 class="mt-4">Subscribe to events</h4> <h4 class="mt-4">Subscribe to events</h4>
<div class="w-64"> <div class="w-64">
@if (isDev()) @if (isDev())
<x-forms.checkbox instantSave="saveModel" id="model.smtp_notifications_test" <x-forms.checkbox instantSave="saveModel" id="model.smtp_notifications_test" label="Test" />
label="Test Notifications" />
@endif @endif
<h5 class="mt-4">Applications</h5> <h5 class="mt-4">Applications</h5>
<x-forms.checkbox instantSave="saveModel" id="model.smtp_notifications_deployments" <x-forms.checkbox instantSave="saveModel" id="model.smtp_notifications_deployments" label="Deployments" />
label="New Deployment" />
<x-forms.checkbox instantSave="saveModel" id="model.smtp_notifications_status_changes" <x-forms.checkbox instantSave="saveModel" id="model.smtp_notifications_status_changes"
label="Status Changes" /> label="Status Changes" />
</div> </div>

View File

@ -8,7 +8,7 @@
</div> </div>
<div class="flex flex-col gap-2 pt-4"> <div class="flex flex-col gap-2 pt-4">
<div class="flex gap-2 w-96"> <div class="flex gap-2 w-96">
<x-forms.input id="settings.fqdn" label="Coolify's Domain" /> <x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://coolify.io" />
</div> </div>
{{-- <div class="flex gap-2 "> {{-- <div class="flex gap-2 ">

View File

@ -1,4 +1,15 @@
<div> <div>
<dialog id="sendTestEmail" class="modal">
<form method="dialog" class="flex flex-col gap-2 rounded modal-box" wire:submit.prevent='submit'>
<x-forms.input placeholder="test@example.com" id="emails" label="Recepients" required />
<x-forms.button onclick="sendTestEmail.close()" wire:click="sendTestNotification">
Send Email
</x-forms.button>
</form>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
</dialog>
<form wire:submit.prevent='submit' class="flex flex-col pb-10"> <form wire:submit.prevent='submit' class="flex flex-col pb-10">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<h3>Transactional Emails</h3> <h3>Transactional Emails</h3>
@ -6,7 +17,8 @@
Save Save
</x-forms.button> </x-forms.button>
@if ($settings->smtp_enabled) @if ($settings->smtp_enabled)
<x-forms.button isHighlighted wire:click='testNotification'> <x-forms.button onclick="sendTestEmail.showModal()"
class="text-white normal-case btn btn-xs no-animation btn-primary">
Send Test Email Send Test Email
</x-forms.button> </x-forms.button>
@endif @endif
@ -17,16 +29,14 @@
</div> </div>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div class="flex flex-col w-full gap-2 xl:flex-row"> <div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input required id="settings.smtp_host" helper="SMTP Hostname" placeholder="smtp.mailgun.org" <x-forms.input required id="settings.smtp_host" placeholder="smtp.mailgun.org" label="Host" />
label="Host" /> <x-forms.input required id="settings.smtp_port" placeholder="587" label="Port" />
<x-forms.input required id="settings.smtp_port" helper="SMTP Port" placeholder="587" label="Port" /> <x-forms.input id="settings.smtp_encryption" helper="If SMTP uses SSL, set it to 'tls'."
<x-forms.input id="settings.smtp_encryption" helper="If SMTP through SSL, set it to 'tls'."
placeholder="tls" label="Encryption" /> placeholder="tls" label="Encryption" />
</div> </div>
<div class="flex flex-col w-full gap-2 xl:flex-row"> <div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input id="settings.smtp_username" helper="SMTP Username" label="SMTP Username" /> <x-forms.input id="settings.smtp_username" label="SMTP Username" />
<x-forms.input id="settings.smtp_password" type="password" helper="SMTP Password" <x-forms.input id="settings.smtp_password" type="password" label="SMTP Password" />
label="SMTP Password" />
<x-forms.input id="settings.smtp_timeout" helper="Timeout value for sending emails." label="Timeout" /> <x-forms.input id="settings.smtp_timeout" helper="Timeout value for sending emails." label="Timeout" />
</div> </div>
<div class="flex flex-col w-full gap-2 xl:flex-row"> <div class="flex flex-col w-full gap-2 xl:flex-row">