refactoring

This commit is contained in:
Andras Bacsai 2023-08-29 14:36:17 +02:00
parent 2f9b7b188a
commit 291b9a84ef
23 changed files with 409 additions and 240 deletions

View File

@ -48,23 +48,23 @@ public function license()
public function force_passoword_reset() { public function force_passoword_reset() {
return view('auth.force-password-reset'); return view('auth.force-password-reset');
} }
public function dashboard() // public function dashboard()
{ // {
$projects = Project::ownedByCurrentTeam()->get(); // $projects = Project::ownedByCurrentTeam()->get();
$servers = Server::ownedByCurrentTeam()->get(); // $servers = Server::ownedByCurrentTeam()->get();
$s3s = S3Storage::ownedByCurrentTeam()->get(); // $s3s = S3Storage::ownedByCurrentTeam()->get();
$resources = 0; // $resources = 0;
foreach ($projects as $project) { // foreach ($projects as $project) {
$resources += $project->applications->count(); // $resources += $project->applications->count();
$resources += $project->postgresqls->count(); // $resources += $project->postgresqls->count();
} // }
return view('dashboard', [ // return view('dashboard', [
'servers' => $servers->count(), // 'servers' => $servers->count(),
'projects' => $projects->count(), // 'projects' => $projects->count(),
'resources' => $resources, // 'resources' => $resources,
's3s' => $s3s, // 's3s' => $s3s,
]); // ]);
} // }
public function boarding() { public function boarding() {
if (currentTeam()->boarding || isDev()) { if (currentTeam()->boarding || isDev()) {
return view('boarding'); return view('boarding');

View File

@ -0,0 +1,32 @@
<?php
namespace App\Http\Livewire;
use App\Models\Project;
use App\Models\S3Storage;
use App\Models\Server;
use Livewire\Component;
class Dashboard extends Component
{
public int $projects = 0;
public int $servers = 0;
public int $s3s = 0;
public int $resources = 0;
public function mount()
{
$this->servers = Server::ownedByCurrentTeam()->get()->count();
$this->s3s = S3Storage::ownedByCurrentTeam()->get()->count();
$projects = Project::ownedByCurrentTeam()->get();
foreach ($projects as $project) {
$this->resources += $project->applications->count();
$this->resources += $project->postgresqls->count();
}
$this->projects = $projects->count();
}
public function render()
{
return view('livewire.dashboard');
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace App\Http\Livewire\Dev;
use App\Models\S3Storage;
use Illuminate\Support\Facades\Storage;
use Livewire\Component;
use Livewire\WithFileUploads;
class S3Test extends Component
{
use WithFileUploads;
public $s3;
public $file;
public function mount()
{
$this->s3 = S3Storage::first();
}
public function save()
{
try {
$this->validate([
'file' => 'required|max:150', // 1MB Max
]);
set_s3_target($this->s3);
$this->file->storeAs('files', $this->file->getClientOriginalName(), 'custom-s3');
$this->emit('success', 'File uploaded successfully.');
} catch (\Throwable $th) {
return general_error_handler($th, $this, false);
}
}
public function get_files()
{
set_s3_target($this->s3);
dd(Storage::disk('custom-s3')->files('files'));
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Http\Livewire\Server;
use App\Models\Server;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Component;
class All extends Component
{
public ?Collection $servers = null;
public function mount () {
$this->servers = Server::ownedByCurrentTeam()->get();
}
public function render()
{
return view('livewire.server.all');
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Http\Livewire\Server;
use App\Models\Server;
use Livewire\Component;
class Show extends Component
{
public ?Server $server = null;
public function mount()
{
$this->server = Server::ownedByCurrentTeam(['name', 'description', 'ip', 'port', 'user', 'proxy'])->whereUuid(request()->server_uuid)->firstOrFail();
}
public function render()
{
return view('livewire.server.show');
}
}

View File

@ -15,7 +15,7 @@ class IsBoardingFlow
*/ */
public function handle(Request $request, Closure $next): Response public function handle(Request $request, Closure $next): Response
{ {
// ray('IsBoardingFlow Middleware'); ray()->showQueries()->color('orange');
if (showBoarding() && !in_array($request->path(), allowedPathsForBoardingAccounts())) { if (showBoarding() && !in_array($request->path(), allowedPathsForBoardingAccounts())) {
return redirect('boarding'); return redirect('boarding');
} }

View File

@ -91,29 +91,20 @@ public function isInstanceAdmin()
return $found_root_team->count() > 0; return $found_root_team->count() > 0;
} }
public function personalTeam()
{
return $this->teams()->where('personal_team', true)->first();
}
public function currentTeam() public function currentTeam()
{ {
return $this->teams()->where('team_id', session('currentTeam')->id)->first(); return session('currentTeam');
} }
public function otherTeams() public function otherTeams()
{ {
$team_id = currentTeam()->id; return auth()->user()->teams->filter(function ($team) {
return auth()->user()->teams->filter(function ($team) use ($team_id) { return $team->id != currentTeam()->id;
return $team->id != $team_id;
}); });
} }
public function role() public function role()
{ {
if ($this->teams()->where('team_id', 0)->first()) { return session('currentTeam')->pivot->role;
return 'admin';
}
return $this->teams()->where('team_id', currentTeam()->id)->first()->pivot->role;
} }
} }

View File

@ -42,7 +42,7 @@
"laravel/pint": "^v1.8.0", "laravel/pint": "^v1.8.0",
"mockery/mockery": "^1.5.1", "mockery/mockery": "^1.5.1",
"nunomaduro/collision": "^v7.4.0", "nunomaduro/collision": "^v7.4.0",
"pestphp/pest": "^v2.4.0", "pestphp/pest": "^2.16",
"phpstan/phpstan": "^1.10", "phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.0.19", "phpunit/phpunit": "^10.0.19",
"serversideup/spin": "^v1.1.0", "serversideup/spin": "^v1.1.0",

142
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "da14dce99d76abcaaa6393166eda049a", "content-hash": "dbb08df7a80c46ce2b9b9fa397ed71c1",
"packages": [ "packages": [
{ {
"name": "aws/aws-crt-php", "name": "aws/aws-crt-php",
@ -6654,16 +6654,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v6.3.2", "version": "v6.3.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898" "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/aa5d64ad3f63f2e48964fc81ee45cb318a723898", "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6",
"reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898", "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6724,7 +6724,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v6.3.2" "source": "https://github.com/symfony/console/tree/v6.3.4"
}, },
"funding": [ "funding": [
{ {
@ -6740,7 +6740,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-19T20:17:28+00:00" "time": "2023-08-16T10:10:12+00:00"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
@ -7761,16 +7761,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a" "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7785,7 +7785,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -7823,7 +7823,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -7839,7 +7839,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-iconv", "name": "symfony/polyfill-iconv",
@ -7926,16 +7926,16 @@
}, },
{ {
"name": "symfony/polyfill-intl-grapheme", "name": "symfony/polyfill-intl-grapheme",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "511a08c03c1960e08a883f4cffcacd219b758354" "reference": "875e90aeea2777b6f135677f618529449334a612"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
"reference": "511a08c03c1960e08a883f4cffcacd219b758354", "reference": "875e90aeea2777b6f135677f618529449334a612",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7947,7 +7947,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -7987,7 +7987,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -8003,7 +8003,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
@ -8094,16 +8094,16 @@
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8115,7 +8115,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -8158,7 +8158,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -8174,20 +8174,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" "reference": "42292d99c55abe617799667f454222c54c60e229"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "reference": "42292d99c55abe617799667f454222c54c60e229",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8202,7 +8202,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -8241,7 +8241,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -8257,7 +8257,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-07-28T09:04:16+00:00"
}, },
{ {
"name": "symfony/polyfill-php72", "name": "symfony/polyfill-php72",
@ -8337,16 +8337,16 @@
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8355,7 +8355,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -8400,7 +8400,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -8416,7 +8416,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-php83", "name": "symfony/polyfill-php83",
@ -8579,16 +8579,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v6.3.2", "version": "v6.3.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d" "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d", "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54",
"reference": "c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d", "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8620,7 +8620,7 @@
"description": "Executes commands in sub-processes", "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/process/tree/v6.3.2" "source": "https://github.com/symfony/process/tree/v6.3.4"
}, },
"funding": [ "funding": [
{ {
@ -8636,7 +8636,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-12T16:00:22+00:00" "time": "2023-08-07T10:39:22+00:00"
}, },
{ {
"name": "symfony/psr-http-message-bridge", "name": "symfony/psr-http-message-bridge",
@ -9982,16 +9982,16 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "brianium/paratest", "name": "brianium/paratest",
"version": "v7.2.5", "version": "v7.2.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paratestphp/paratest.git", "url": "https://github.com/paratestphp/paratest.git",
"reference": "4d7ad5b6564f63baa1b948ecad05439f22880942" "reference": "7f372b5bb59b4271adedc67d3129df29b84c4173"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paratestphp/paratest/zipball/4d7ad5b6564f63baa1b948ecad05439f22880942", "url": "https://api.github.com/repos/paratestphp/paratest/zipball/7f372b5bb59b4271adedc67d3129df29b84c4173",
"reference": "4d7ad5b6564f63baa1b948ecad05439f22880942", "reference": "7f372b5bb59b4271adedc67d3129df29b84c4173",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -10005,19 +10005,19 @@
"phpunit/php-code-coverage": "^10.1.3", "phpunit/php-code-coverage": "^10.1.3",
"phpunit/php-file-iterator": "^4.0.2", "phpunit/php-file-iterator": "^4.0.2",
"phpunit/php-timer": "^6.0", "phpunit/php-timer": "^6.0",
"phpunit/phpunit": "^10.3.1", "phpunit/phpunit": "^10.3.2",
"sebastian/environment": "^6.0.1", "sebastian/environment": "^6.0.1",
"symfony/console": "^6.3.2", "symfony/console": "^6.3.4",
"symfony/process": "^6.3.2" "symfony/process": "^6.3.4"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^12.0.0", "doctrine/coding-standard": "^12.0.0",
"ext-pcov": "*", "ext-pcov": "*",
"ext-posix": "*", "ext-posix": "*",
"infection/infection": "^0.27.0", "infection/infection": "^0.27.0",
"phpstan/phpstan": "^1.10.26", "phpstan/phpstan": "^1.10.32",
"phpstan/phpstan-deprecation-rules": "^1.1.3", "phpstan/phpstan-deprecation-rules": "^1.1.4",
"phpstan/phpstan-phpunit": "^1.3.13", "phpstan/phpstan-phpunit": "^1.3.14",
"phpstan/phpstan-strict-rules": "^1.5.1", "phpstan/phpstan-strict-rules": "^1.5.1",
"squizlabs/php_codesniffer": "^3.7.2", "squizlabs/php_codesniffer": "^3.7.2",
"symfony/filesystem": "^6.3.1" "symfony/filesystem": "^6.3.1"
@ -10061,7 +10061,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/paratestphp/paratest/issues", "issues": "https://github.com/paratestphp/paratest/issues",
"source": "https://github.com/paratestphp/paratest/tree/v7.2.5" "source": "https://github.com/paratestphp/paratest/tree/v7.2.6"
}, },
"funding": [ "funding": [
{ {
@ -10073,7 +10073,7 @@
"type": "paypal" "type": "paypal"
} }
], ],
"time": "2023-08-08T13:23:59+00:00" "time": "2023-08-29T07:47:39+00:00"
}, },
{ {
"name": "fakerphp/faker", "name": "fakerphp/faker",
@ -10707,24 +10707,24 @@
}, },
{ {
"name": "pestphp/pest", "name": "pestphp/pest",
"version": "v2.16.0", "version": "v2.16.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pestphp/pest.git", "url": "https://github.com/pestphp/pest.git",
"reference": "cbd6a650576714c673dbb0575989663f7f5c8b6d" "reference": "55b92666482b7d4320b7869c4eea7333d35c5631"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pestphp/pest/zipball/cbd6a650576714c673dbb0575989663f7f5c8b6d", "url": "https://api.github.com/repos/pestphp/pest/zipball/55b92666482b7d4320b7869c4eea7333d35c5631",
"reference": "cbd6a650576714c673dbb0575989663f7f5c8b6d", "reference": "55b92666482b7d4320b7869c4eea7333d35c5631",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"brianium/paratest": "^7.2.5", "brianium/paratest": "^7.2.6",
"nunomaduro/collision": "^7.8.1", "nunomaduro/collision": "^7.8.1",
"nunomaduro/termwind": "^1.15.1", "nunomaduro/termwind": "^1.15.1",
"pestphp/pest-plugin": "^2.0.1", "pestphp/pest-plugin": "^2.1.1",
"pestphp/pest-plugin-arch": "^2.3.1", "pestphp/pest-plugin-arch": "^2.3.3",
"php": "^8.1.0", "php": "^8.1.0",
"phpunit/phpunit": "^10.3.2" "phpunit/phpunit": "^10.3.2"
}, },
@ -10734,8 +10734,8 @@
}, },
"require-dev": { "require-dev": {
"pestphp/pest-dev-tools": "^2.16.0", "pestphp/pest-dev-tools": "^2.16.0",
"pestphp/pest-plugin-type-coverage": "^2.0.0", "pestphp/pest-plugin-type-coverage": "^2.2.0",
"symfony/process": "^6.3.2" "symfony/process": "^6.3.4"
}, },
"bin": [ "bin": [
"bin/pest" "bin/pest"
@ -10793,7 +10793,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/pestphp/pest/issues", "issues": "https://github.com/pestphp/pest/issues",
"source": "https://github.com/pestphp/pest/tree/v2.16.0" "source": "https://github.com/pestphp/pest/tree/v2.16.1"
}, },
"funding": [ "funding": [
{ {
@ -10805,7 +10805,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2023-08-21T08:42:07+00:00" "time": "2023-08-29T09:30:36+00:00"
}, },
{ {
"name": "pestphp/pest-plugin", "name": "pestphp/pest-plugin",

View File

@ -18,7 +18,7 @@
| |
*/ */
'driver' => env('SESSION_DRIVER', 'database'), 'driver' => env('SESSION_DRIVER', 'redis'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -15,10 +15,12 @@ public function run(): void
'email' => 'test@example.com', 'email' => 'test@example.com',
]); ]);
User::factory()->create([ User::factory()->create([
'id' => 1,
'name' => 'Normal User (but in root team)', 'name' => 'Normal User (but in root team)',
'email' => 'test2@example.com', 'email' => 'test2@example.com',
]); ]);
User::factory()->create([ User::factory()->create([
'id' => 2,
'name' => 'Normal User (not in root team)', 'name' => 'Normal User (not in root team)',
'email' => 'test3@example.com', 'email' => 'test3@example.com',
]); ]);

View File

@ -1,31 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" <testsuites>
bootstrap="vendor/autoload.php" <testsuite name="Unit">
colors="true" <directory suffix="Test.php">./tests/Unit</directory>
> </testsuite>
<testsuites> <testsuite name="Feature">
<testsuite name="Unit"> <directory suffix="Test.php">./tests/Feature</directory>
<directory suffix="Test.php">./tests/Unit</directory> </testsuite>
</testsuite> </testsuites>
<testsuite name="Feature"> <coverage/>
<directory suffix="Test.php">./tests/Feature</directory> <php>
</testsuite> <env name="APP_ENV" value="testing"/>
</testsuites> <env name="BCRYPT_ROUNDS" value="4"/>
<coverage> <env name="CACHE_DRIVER" value="array"/>
<include> <!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<directory suffix=".php">./app</directory> <!-- <env name="DB_DATABASE" value=":memory:"/> -->
</include> <env name="MAIL_MAILER" value="array"/>
</coverage> <env name="QUEUE_CONNECTION" value="sync"/>
<php> <env name="SESSION_DRIVER" value="array"/>
<env name="APP_ENV" value="testing"/> <env name="TELESCOPE_ENABLED" value="false"/>
<env name="BCRYPT_ROUNDS" value="4"/> </php>
<env name="CACHE_DRIVER" value="array"/> <source>
<!-- <env name="DB_CONNECTION" value="sqlite"/> --> <include>
<!-- <env name="DB_DATABASE" value=":memory:"/> --> <directory suffix=".php">./app</directory>
<env name="MAIL_MAILER" value="array"/> </include>
<env name="QUEUE_CONNECTION" value="sync"/> </source>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit> </phpunit>

View File

@ -0,0 +1,133 @@
<!DOCTYPE html>
<html data-theme="coollabs" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://api.fonts.coollabs.io" crossorigin>
<link href="https://api.fonts.coollabs.io/css2?family=Inter&display=swap" rel="stylesheet">
@env('local')
<title>Coolify - localhost</title>
<link rel="icon" href="{{ asset('favicon-dev.png') }}" type="image/x-icon" />
@else
<title>{{ $title ?? 'Coolify' }}</title>
<link rel="icon" href="{{ asset('coolify-transparent.png') }}" type="image/x-icon" />
@endenv
<meta name="csrf-token" content="{{ csrf_token() }}">
@vite(['resources/js/app.js', 'resources/css/app.css'])
<style>
[x-cloak] {
display: none !important;
}
</style>
@livewireStyles
</head>
<body>
@livewireScripts
@auth
<x-toaster-hub />
<x-navbar />
<div class="fixed top-3 left-4" id="vue">
<magic-bar></magic-bar>
</div>
<main class="main max-w-screen-2xl">
{{ $slot }}
</main>
<x-version class="fixed left-2 bottom-1" />
<script>
let checkHealthInterval = null;
let checkIfIamDeadInterval = null;
function changePasswordFieldType(event) {
let element = event.target
for (let i = 0; i < 10; i++) {
if (element.className === "relative") {
break;
}
element = element.parentElement;
}
element = element.children[1];
if (element.nodeName === 'INPUT') {
if (element.type === 'password') {
element.type = 'text';
} else {
element.type = 'password';
}
}
}
function revive() {
if (checkHealthInterval) return true;
console.log('Checking server\'s health...')
checkHealthInterval = setInterval(() => {
fetch('/api/health')
.then(response => {
if (response.ok) {
Toaster.success('Coolify is back online. Reloading...')
if (checkHealthInterval) clearInterval(checkHealthInterval);
setTimeout(() => {
window.location.reload();
}, 5000)
} else {
console.log('Waiting for server to come back from dead...');
}
})
}, 2000);
}
function upgrade() {
if (checkIfIamDeadInterval) return true;
console.log('Update initiated.')
checkIfIamDeadInterval = setInterval(() => {
fetch('/api/health')
.then(response => {
if (response.ok) {
console.log('It\'s alive. Waiting for server to be dead...');
} else {
Toaster.success('Update done, restarting Coolify!')
console.log('It\'s dead. Reviving... Standby... Bzz... Bzz...')
if (checkIfIamDeadInterval) clearInterval(checkIfIamDeadInterval);
revive();
}
})
}, 2000);
}
function copyToClipboard(text) {
navigator.clipboard.writeText(text);
Livewire.emit('message', 'Copied to clipboard.');
}
Livewire.on('reloadWindow', (timeout) => {
if (timeout) {
setTimeout(() => {
window.location.reload();
}, timeout);
return;
} else {
window.location.reload();
}
})
Livewire.on('info', (message) => {
if (message) Toaster.info(message)
})
Livewire.on('error', (message) => {
if (message) Toaster.error(message)
})
Livewire.on('warning', (message) => {
if (message) Toaster.warning(message)
})
Livewire.on('success', (message) => {
if (message) Toaster.success(message)
})
</script>
@endauth
@guest
{{ $slot }}
@endguest
</body>
</html>

View File

@ -1,4 +1,4 @@
<x-layout> <div>
<h1>Dashboard</h1> <h1>Dashboard</h1>
<div class="subtitle">Something <x-highlighted text="(more)"/> useful will be here.</div> <div class="subtitle">Something <x-highlighted text="(more)"/> useful will be here.</div>
<div class="w-full rounded stats stats-vertical lg:stats-horizontal"> <div class="w-full rounded stats stats-vertical lg:stats-horizontal">
@ -19,10 +19,7 @@
</div> </div>
<div class="stat"> <div class="stat">
<div class="stat-title">S3 Storages</div> <div class="stat-title">S3 Storages</div>
<div class="stat-value">{{ $s3s->count() }}</div> <div class="stat-value">{{ $s3s }}</div>
</div> </div>
</div> </div>
@if (isDev()) </div>
{{-- <livewire:dev.s3-test /> --}}
@endif
</x-layout>

View File

@ -0,0 +1,54 @@
<div>
<div class="flex items-start gap-2">
<h1>Servers</h1>
<a class="text-white hover:no-underline" href="{{ route('server.create') }}">
<x-forms.button class="btn">+ Add</x-forms.button>
</a>
</div>
<div class="subtitle ">All Servers</div>
<div class="grid gap-2 lg:grid-cols-2">
@forelse ($servers as $server)
<a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
@class([
'gap-2 border cursor-pointer box group',
'border-transparent' => $server->settings->is_reachable,
'border-red-500' => !$server->settings->is_reachable,
])>
<div class="flex flex-col mx-6">
<div class=" group-hover:text-white">
{{ $server->name }}
</div>
<div class="text-xs group-hover:text-white">
{{ $server->description }}</div>
<div class="flex gap-1 text-xs text-error">
@if (!$server->settings->is_reachable)
<span>Not reachable</span>
@endif
@if (!$server->settings->is_reachable && !$server->settings->is_usable)
&
@endif
@if (!$server->settings->is_usable)
<span>Not usable by Coolify</span>
@endif
</div>
</div>
<div class="flex-1"></div>
</a>
@empty
<div>
<div>No servers found. Without a server, you won't be able to do much.</div>
<x-use-magic-bar link="/server/new" />
</div>
@endforelse
@isset($error)
<div class="text-center text-error">
<span>{{ $error }}</span>
</div>
@endisset
<script>
function goto(uuid) {
window.location.href = '/server/' + uuid;
}
</script>
</div>
</div>

View File

@ -0,0 +1,4 @@
<div>
<x-server.navbar :server="$server" />
<livewire:server.form :server="$server" />
</div>

View File

@ -1,53 +1,3 @@
<x-layout> <x-layout>
<div class="flex items-start gap-2">
<h1>Servers</h1>
<a class="text-white hover:no-underline" href="/server/new"> <x-forms.button class="btn">+ Add
</x-forms.button></a>
</div>
<div class="subtitle ">All Servers</div>
<div class="grid gap-2 lg:grid-cols-2">
@forelse ($servers as $server)
<div x-data x-on:click="goto('{{ $server->uuid }}')" @class([
'gap-2 border cursor-pointer box group',
'border-transparent' => $server->settings->is_reachable,
'border-red-500' => !$server->settings->is_reachable,
])>
<div class="flex flex-col mx-6">
<div class=" group-hover:text-white">
{{ $server->name }}
</div>
<div class="text-xs group-hover:text-white"
href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}">
{{ $server->description }}</div>
<div class="flex gap-1 text-xs text-error">
@if (!$server->settings->is_reachable)
<span>Not reachable</span>
@endif
@if (!$server->settings->is_reachable && !$server->settings->is_usable)
&
@endif
@if (!$server->settings->is_usable)
<span>Not usable by Coolify</span>
@endif
</div>
</div>
<div class="flex-1"></div>
</div>
@empty
<div>
<div>No servers found. Without a server, you won't be able to do much.</div>
<x-use-magic-bar link="/server/new" />
</div>
@endforelse
@isset($error)
<div class="text-center text-error">
<span>{{ $error }}</span>
</div>
@endisset
<script>
function goto(uuid) {
window.location.href = '/server/' + uuid;
}
</script>
</div>
</x-layout> </x-layout>

View File

@ -6,6 +6,9 @@
use App\Http\Controllers\MagicController; use App\Http\Controllers\MagicController;
use App\Http\Controllers\ProjectController; use App\Http\Controllers\ProjectController;
use App\Http\Controllers\ServerController; use App\Http\Controllers\ServerController;
use App\Http\Livewire\Dashboard;
use App\Http\Livewire\Server\All;
use App\Http\Livewire\Server\Show;
use App\Models\GithubApp; use App\Models\GithubApp;
use App\Models\GitlabApp; use App\Models\GitlabApp;
use App\Models\InstanceSettings; use App\Models\InstanceSettings;
@ -71,13 +74,9 @@
}); });
Route::middleware(['auth'])->group(function () { Route::middleware(['auth'])->group(function () {
Route::get('/servers', fn () => view('server.all', [ Route::get('/servers', All::class)->name('server.all');
'servers' => Server::ownedByCurrentTeam()->get()
]))->name('server.all');
Route::get('/server/new', [ServerController::class, 'new_server'])->name('server.create'); Route::get('/server/new', [ServerController::class, 'new_server'])->name('server.create');
Route::get('/server/{server_uuid}', fn () => view('server.show', [ Route::get('/server/{server_uuid}', Show::class)->name('server.show');
'server' => Server::ownedByCurrentTeam(['name', 'description', 'ip', 'port', 'user', 'proxy'])->whereUuid(request()->server_uuid)->firstOrFail(),
]))->name('server.show');
Route::get('/server/{server_uuid}/proxy', fn () => view('server.proxy', [ Route::get('/server/{server_uuid}/proxy', fn () => view('server.proxy', [
'server' => Server::ownedByCurrentTeam(['name', 'proxy'])->whereUuid(request()->server_uuid)->firstOrFail(), 'server' => Server::ownedByCurrentTeam(['name', 'proxy'])->whereUuid(request()->server_uuid)->firstOrFail(),
]))->name('server.proxy'); ]))->name('server.proxy');
@ -92,9 +91,9 @@
Route::middleware(['auth'])->group(function () { Route::middleware(['auth'])->group(function () {
Route::get('/', [Controller::class, 'dashboard'])->name('dashboard'); Route::get('/', Dashboard::class)->name('dashboard');
Route::get('/boarding', [Controller::class, 'boarding'])->name('boarding'); Route::get('/boarding', [Controller::class, 'boarding'])->name('boarding');
Route::middleware(['throttle:force-password-reset'])->group(function() { Route::middleware(['throttle:force-password-reset'])->group(function () {
Route::get('/force-password-reset', [Controller::class, 'force_passoword_reset'])->name('auth.force-password-reset'); Route::get('/force-password-reset', [Controller::class, 'force_passoword_reset'])->name('auth.force-password-reset');
}); });
Route::get('/subscription', [Controller::class, 'subscription'])->name('subscription.show'); Route::get('/subscription', [Controller::class, 'subscription'])->name('subscription.show');

View File

@ -0,0 +1,7 @@
<?php
it('returns a successful response', function () {
$response = $this->get('/api/health');
$response->assertStatus(200);
});

View File

@ -0,0 +1,5 @@
<?php
test('that true is true', function () {
expect(true)->toBeTrue();
});

View File

@ -1,5 +1,5 @@
<?php <?php
test('globals') test('globals')
->expect(['dd', 'dump', 'ray']) ->expect(['dd', 'dump'])
->not->toBeUsed(); ->not->toBeUsed();