wip: migrate to livewire 3

This commit is contained in:
Andras Bacsai
2023-12-07 19:06:32 +01:00
parent 2f286a6595
commit 718603e37e
254 changed files with 930 additions and 936 deletions

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Livewire\Team;
use App\Models\Team;
use Livewire\Component;
class Create extends Component
{
public string $name = '';
public string|null $description = null;
protected $rules = [
'name' => 'required|min:3|max:255',
'description' => 'nullable|min:3|max:255',
];
protected $validationAttributes = [
'name' => 'name',
'description' => 'description',
];
public function submit()
{
$this->validate();
try {
$team = Team::create([
'name' => $this->name,
'description' => $this->description,
'personal_team' => false,
]);
auth()->user()->teams()->attach($team, ['role' => 'admin']);
refreshSession();
return redirect()->route('team.index');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Livewire\Team;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
class Delete extends Component
{
public function delete()
{
$currentTeam = currentTeam();
$currentTeam->delete();
$currentTeam->members->each(function ($user) use ($currentTeam) {
if ($user->id === auth()->user()->id) {
return;
}
$user->teams()->detach($currentTeam);
$session = DB::table('sessions')->where('user_id', $user->id)->first();
if ($session) {
DB::table('sessions')->where('id', $session->id)->delete();
}
});
refreshSession();
return redirect()->route('team.index');
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Livewire\Team;
use App\Models\Team;
use Livewire\Component;
class Form extends Component
{
public Team $team;
protected $rules = [
'team.name' => 'required|min:3|max:255',
'team.description' => 'nullable|min:3|max:255',
];
protected $validationAttributes = [
'team.name' => 'name',
'team.description' => 'description',
];
public function mount()
{
$this->team = currentTeam();
}
public function submit()
{
$this->validate();
try {
$this->team->save();
refreshSession();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Livewire\Team;
use App\Models\TeamInvitation;
use Livewire\Component;
class Invitations extends Component
{
public $invitations;
protected $listeners = ['refreshInvitations'];
public function deleteInvitation(int $invitation_id)
{
TeamInvitation::find($invitation_id)->delete();
$this->refreshInvitations();
$this->dispatch('success', 'Invitation revoked.');
}
public function refreshInvitations()
{
$this->invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get();
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace App\Livewire\Team;
use App\Models\TeamInvitation;
use App\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Artisan;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class InviteLink extends Component
{
public string $email;
public string $role = 'member';
public function mount()
{
$this->email = isDev() ? 'test3@example.com' : '';
}
public function viaEmail()
{
$this->generate_invite_link(sendEmail: true);
}
public function viaLink()
{
$this->generate_invite_link(sendEmail: false);
}
private function generate_invite_link(bool $sendEmail = false)
{
try {
$member_emails = currentTeam()->members()->get()->pluck('email');
if ($member_emails->contains($this->email)) {
return handleError(livewire: $this, customErrorMessage: "$this->email is already a member of " . currentTeam()->name . ".");
}
$uuid = new Cuid2(32);
$link = url('/') . config('constants.invitation.link.base_url') . $uuid;
$user = User::whereEmail($this->email)->first();
if (is_null($user)) {
$password = Str::password();
$user = User::create([
'name' => Str::of($this->email)->before('@'),
'email' => $this->email,
'password' => Hash::make($password),
'force_password_reset' => true,
]);
$token = Crypt::encryptString("{$user->email}@@@$password");
$link = route('auth.link', ['token' => $token]);
}
$invitation = TeamInvitation::whereEmail($this->email)->first();
if (!is_null($invitation)) {
$invitationValid = $invitation->isValid();
if ($invitationValid) {
return handleError(livewire: $this, customErrorMessage: "Pending invitation already exists for $this->email.");
} else {
$invitation->delete();
}
}
$invitation = TeamInvitation::firstOrCreate([
'team_id' => currentTeam()->id,
'uuid' => $uuid,
'email' => $this->email,
'role' => $this->role,
'link' => $link,
'via' => $sendEmail ? 'email' : 'link',
]);
if ($sendEmail) {
$mail = new MailMessage();
$mail->view('emails.invitation-link', [
'team' => currentTeam()->name,
'invitation_link' => $link,
]);
$mail->subject('You have been invited to ' . currentTeam()->name . ' on ' . config('app.name') . '.');
send_user_an_email($mail, $this->email);
$this->dispatch('success', 'Invitation sent via email successfully.');
$this->dispatch('refreshInvitations');
return;
} else {
$this->dispatch('success', 'Invitation link generated.');
$this->dispatch('refreshInvitations');
}
} catch (\Throwable $e) {
$error_message = $e->getMessage();
if ($e->getCode() === '23505') {
$error_message = 'Invitation already sent.';
}
return handleError(error: $e, livewire: $this, customErrorMessage: $error_message);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Livewire\Team;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Livewire\Component;
class Member extends Component
{
public User $member;
public function makeAdmin()
{
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'admin']);
$this->dispatch('reloadWindow');
}
public function makeReadonly()
{
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'member']);
$this->dispatch('reloadWindow');
}
public function remove()
{
$this->member->teams()->detach(currentTeam());
Cache::forget("team:{$this->member->id}");
Cache::remember('team:' . $this->member->id, 3600, function() {
return $this->member->teams()->first();
});
$this->dispatch('reloadWindow');
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Livewire\Team\Storage;
use App\Models\S3Storage;
use Livewire\Component;
class Create extends Component
{
public string $name;
public string $description;
public string $region = 'us-east-1';
public string $key;
public string $secret;
public string $bucket;
public string $endpoint;
public S3Storage $storage;
protected $rules = [
'name' => 'nullable|min:3|max:255',
'description' => 'nullable|min:3|max:255',
'region' => 'required|max:255',
'key' => 'required|max:255',
'secret' => 'required|max:255',
'bucket' => 'required|max:255',
'endpoint' => 'nullable|url|max:255',
];
protected $validationAttributes = [
'name' => 'Name',
'description' => 'Description',
'region' => 'Region',
'key' => 'Key',
'secret' => "Secret",
'bucket' => 'Bucket',
'endpoint' => 'Endpoint',
];
public function mount()
{
if (isDev()) {
$this->name = 'Local MinIO';
$this->description = 'Local MinIO';
$this->key = 'minioadmin';
$this->secret = 'minioadmin';
$this->bucket = 'local';
$this->endpoint = 'http://coolify-minio:9000';
}
}
public function submit()
{
try {
$this->validate();
$this->storage = new S3Storage();
$this->storage->name = $this->name;
$this->storage->description = $this->description ?? null;
$this->storage->region = $this->region;
$this->storage->key = $this->key;
$this->storage->secret = $this->secret;
$this->storage->bucket = $this->bucket;
if (empty($this->endpoint)) {
$this->storage->endpoint = "https://s3.{$this->region}.amazonaws.com";
} else {
$this->storage->endpoint = $this->endpoint;
}
$this->storage->team_id = currentTeam()->id;
$this->storage->testConnection();
$this->storage->save();
return redirect()->route('team.storages.show', $this->storage->uuid);
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace App\Livewire\Team\Storage;
use App\Models\S3Storage;
use Livewire\Component;
class Form extends Component
{
public S3Storage $storage;
protected $rules = [
'storage.is_usable' => 'nullable|boolean',
'storage.name' => 'nullable|min:3|max:255',
'storage.description' => 'nullable|min:3|max:255',
'storage.region' => 'required|max:255',
'storage.key' => 'required|max:255',
'storage.secret' => 'required|max:255',
'storage.bucket' => 'required|max:255',
'storage.endpoint' => 'required|url|max:255',
];
protected $validationAttributes = [
'storage.is_usable' => 'Is Usable',
'storage.name' => 'Name',
'storage.description' => 'Description',
'storage.region' => 'Region',
'storage.key' => 'Key',
'storage.secret' => "Secret",
'storage.bucket' => 'Bucket',
'storage.endpoint' => 'Endpoint',
];
public function test_s3_connection()
{
try {
$this->storage->testConnection(shouldSave: true);
return $this->dispatch('success', 'Connection is working. Tested with "ListObjectsV2" action.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function delete()
{
try {
$this->storage->delete();
return redirect()->route('team.storages.all');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function submit()
{
$this->validate();
try {
$this->test_s3_connection();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
}