Skip to content

Commit

Permalink
source-controls (#193)
Browse files Browse the repository at this point in the history
* edit source control
* assign project after creation
* global and project scoped source controls
  • Loading branch information
saeedvaziry authored May 7, 2024
1 parent e704a13 commit 179aefe
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 10 deletions.
6 changes: 4 additions & 2 deletions app/Actions/Projects/CreateProject.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ public function create(User $user, array $input): Project
$input['name'] = strtolower($input['name']);
}

$this->validate($user, $input);
$this->validate($input);

$project = new Project([
'name' => $input['name'],
]);

$project->save();

$project->users()->attach($user);

return $project;
}

private function validate(User $user, array $input): void
private function validate(array $input): void
{
Validator::make($input, [
'name' => [
Expand Down
4 changes: 3 additions & 1 deletion app/Actions/SourceControl/ConnectSourceControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@
namespace App\Actions\SourceControl;

use App\Models\SourceControl;
use App\Models\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;

class ConnectSourceControl
{
public function connect(array $input): void
public function connect(User $user, array $input): void
{
$this->validate($input);

$sourceControl = new SourceControl([
'provider' => $input['provider'],
'profile' => $input['name'],
'url' => Arr::has($input, 'url') ? $input['url'] : null,
'project_id' => isset($input['global']) && $input['global'] ? null : $user->current_project_id,
]);

$this->validateProvider($sourceControl, $input);
Expand Down
54 changes: 54 additions & 0 deletions app/Actions/SourceControl/EditSourceControl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace App\Actions\SourceControl;

use App\Models\SourceControl;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;

class EditSourceControl
{
public function edit(SourceControl $sourceControl, User $user, array $input): void
{
$this->validate($input);

$sourceControl->profile = $input['name'];
$sourceControl->url = isset($input['url']) ? $input['url'] : null;
$sourceControl->project_id = isset($input['global']) && $input['global'] ? null : $user->current_project_id;

$this->validateProvider($sourceControl, $input);

$sourceControl->provider_data = $sourceControl->provider()->createData($input);

if (! $sourceControl->provider()->connect()) {
throw ValidationException::withMessages([
'token' => __('Cannot connect to :provider or invalid token!', ['provider' => $sourceControl->provider]
),
]);
}

$sourceControl->save();
}

/**
* @throws ValidationException
*/
private function validate(array $input): void
{
$rules = [
'name' => [
'required',
],
];
Validator::make($input, $rules)->validate();
}

/**
* @throws ValidationException
*/
private function validateProvider(SourceControl $sourceControl, array $input): void
{
Validator::make($input, $sourceControl->provider()->createRules($input))->validate();
}
}
29 changes: 25 additions & 4 deletions app/Http/Controllers/Settings/SourceControlController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Actions\SourceControl\ConnectSourceControl;
use App\Actions\SourceControl\DeleteSourceControl;
use App\Actions\SourceControl\EditSourceControl;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
Expand All @@ -14,16 +15,23 @@

class SourceControlController extends Controller
{
public function index(): View
public function index(Request $request): View
{
return view('settings.source-controls.index', [
'sourceControls' => SourceControl::query()->orderByDesc('id')->get(),
]);
$data = [
'sourceControls' => SourceControl::getByCurrentProject(),
];

if ($request->has('edit')) {
$data['editSourceControl'] = SourceControl::find($request->input('edit'));
}

return view('settings.source-controls.index', $data);
}

public function connect(Request $request): HtmxResponse
{
app(ConnectSourceControl::class)->connect(
$request->user(),
$request->input(),
);

Expand All @@ -32,6 +40,19 @@ public function connect(Request $request): HtmxResponse
return htmx()->redirect(route('settings.source-controls'));
}

public function update(SourceControl $sourceControl, Request $request): HtmxResponse
{
app(EditSourceControl::class)->edit(
$sourceControl,
$request->user(),
$request->input(),
);

Toast::success('Source control updated.');

return htmx()->redirect(route('settings.source-controls'));
}

public function delete(SourceControl $sourceControl): RedirectResponse
{
try {
Expand Down
6 changes: 6 additions & 0 deletions app/Models/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* @property User $user
* @property Collection<Server> $servers
* @property Collection<NotificationChannel> $notificationChannels
* @property Collection<SourceControl> $sourceControls
*/
class Project extends Model
{
Expand Down Expand Up @@ -59,4 +60,9 @@ public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'user_project')->withTimestamps();
}

public function sourceControls(): HasMany
{
return $this->hasMany(SourceControl::class);
}
}
17 changes: 17 additions & 0 deletions app/Models/SourceControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace App\Models;

use App\SourceControlProviders\SourceControlProvider;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

/**
Expand All @@ -12,6 +14,7 @@
* @property ?string $profile
* @property ?string $url
* @property string $access_token
* @property ?int $project_id
*/
class SourceControl extends AbstractModel
{
Expand All @@ -23,11 +26,13 @@ class SourceControl extends AbstractModel
'profile',
'url',
'access_token',
'project_id',
];

protected $casts = [
'access_token' => 'encrypted',
'provider_data' => 'encrypted:array',
'project_id' => 'integer',
];

public function provider(): SourceControlProvider
Expand All @@ -46,4 +51,16 @@ public function sites(): HasMany
{
return $this->hasMany(Site::class);
}

public function project(): BelongsTo
{
return $this->belongsTo(Project::class);
}

public static function getByCurrentProject(): Collection
{
return self::query()
->where('project_id', auth()->user()->current_project_id)
->orWhereNull('project_id')->get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('source_controls', function (Blueprint $table) {
$table->unsignedBigInteger('project_id')->nullable();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('source_controls', function (Blueprint $table) {
$table->dropColumn('project_id');
});
}
};
19 changes: 19 additions & 0 deletions resources/views/components/checkbox.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@props([
"disabled" => false,
"id",
"name",
"value",
])

<div class="flex items-center">
<input
id="{{ $id }}"
name="{{ $name }}"
type="checkbox"
value="{{ $value }}"
{{ $attributes->merge(["disabled" => $disabled, "class" => "rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800"]) }}
/>
<label for="{{ $id }}" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">
{{ $slot }}
</label>
</div>
4 changes: 3 additions & 1 deletion resources/views/components/modal.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

<div
x-data="{
show: @js($show),
forceShow: @js($show),
show: false,
focusables() {
// All focusable element types...
let selector = 'a, button, input:not([type=\'hidden\']), textarea, select, details, [tabindex]:not([tabindex=\'-1\'])'
Expand All @@ -34,6 +35,7 @@
prevFocusableIndex() { return Math.max(0, this.focusables().indexOf(document.activeElement)) -1 },
}"
x-init="
setTimeout(() => (show = forceShow), 100)
$watch('show', (value) => {
if (value) {
document.body.classList.add('overflow-y-hidden')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ class="text-primary-500"
</div>
</div>

<div class="mt-6">
<x-checkbox id="global" name="global" :checked="old('global')" value="1">
Is Global (Accessible in all projects)
</x-checkbox>
@error("global")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>

<div class="mt-6 flex justify-end">
<x-secondary-button type="button" x-on:click="$dispatch('close')">
{{ __("Cancel") }}
Expand Down
Loading

0 comments on commit 179aefe

Please sign in to comment.