From 3f9b83ec162f52ea68db271e179bd41d3739b223 Mon Sep 17 00:00:00 2001 From: Twyco Date: Wed, 25 Mar 2026 01:16:09 +0100 Subject: [PATCH 1/2] Implement board columns and project workflow settings --- .../ProjectBoardSettingsController.php | 150 ++++++++++++ app/Http/Requests/StoreBoardColumnRequest.php | 41 ++++ .../Requests/UpdateBoardColumnRequest.php | 35 +++ app/Models/BoardColumn.php | 21 ++ app/Models/Project.php | 7 + database/factories/BoardColumnFactory.php | 27 +++ ...3_25_002100_create_board_columns_table.php | 32 +++ database/seeders/BoardColumnSeeder.php | 31 +++ database/seeders/DatabaseSeeder.php | 1 + resources/js/pages/projects/Show.vue | 9 +- .../js/pages/projects/settings/Board.vue | 226 ++++++++++++++++++ .../js/types/models/board-column-model.ts | 9 + resources/js/types/page-props.ts | 7 + routes/web.php | 12 + tests/Feature/Models/BoardColumnTest.php | 83 +++++++ tests/Feature/Models/ProjectTest.php | 47 ++++ .../ProjectBoardSettingsControllerTest.php | 158 ++++++++++++ 17 files changed, 895 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/ProjectBoardSettingsController.php create mode 100644 app/Http/Requests/StoreBoardColumnRequest.php create mode 100644 app/Http/Requests/UpdateBoardColumnRequest.php create mode 100644 app/Models/BoardColumn.php create mode 100644 database/factories/BoardColumnFactory.php create mode 100644 database/migrations/2026_03_25_002100_create_board_columns_table.php create mode 100644 database/seeders/BoardColumnSeeder.php create mode 100644 resources/js/pages/projects/settings/Board.vue create mode 100644 resources/js/types/models/board-column-model.ts create mode 100644 tests/Feature/Models/BoardColumnTest.php create mode 100644 tests/Feature/Projects/ProjectBoardSettingsControllerTest.php diff --git a/app/Http/Controllers/ProjectBoardSettingsController.php b/app/Http/Controllers/ProjectBoardSettingsController.php new file mode 100644 index 0000000..ccb9e1a --- /dev/null +++ b/app/Http/Controllers/ProjectBoardSettingsController.php @@ -0,0 +1,150 @@ +projectPermissionService->userCanManageProjectAccess($request->user(), $project), + 403, + ); + + return Inertia::render('projects/settings/Board', [ + 'boardColumns' => $project->boardColumns()->get(), + 'project' => $project, + 'status' => session('status'), + ]); + } + + public function store( + StoreBoardColumnRequest $request, + Project $project, + ): RedirectResponse { + abort_unless( + $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + 403, + ); + + $desiredPosition = $request->position() ?? $project->boardColumns()->count() + 1; + + $boardColumn = DB::transaction(function () use ($project, $request, $desiredPosition): BoardColumn { + $boardColumn = $project->boardColumns()->create([ + 'name' => $request->validated('name'), + 'position' => $project->boardColumns()->count() + 1, + ]); + + $this->reorderColumns($project, $boardColumn, $desiredPosition); + + return $boardColumn; + }); + + return to_route('projects.settings.board', $project) + ->with('status', "{$boardColumn->name} was added to the board workflow."); + } + + public function update( + UpdateBoardColumnRequest $request, + Project $project, + BoardColumn $boardColumn, + ): RedirectResponse { + abort_unless( + $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + 403, + ); + + DB::transaction(function () use ($boardColumn, $project, $request): void { + $boardColumn->update([ + 'name' => $request->validated('name'), + ]); + + $this->reorderColumns($project, $boardColumn, $request->position()); + }); + + return to_route('projects.settings.board', $project) + ->with('status', "{$boardColumn->fresh()->name} was updated."); + } + + public function destroy( + Request $request, + Project $project, + BoardColumn $boardColumn, + ): RedirectResponse { + abort_unless( + $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + 403, + ); + + $deletedName = $boardColumn->name; + + DB::transaction(function () use ($boardColumn, $project): void { + $boardColumn->delete(); + + $this->normalizeColumnPositions($project); + }); + + return to_route('projects.settings.board', $project) + ->with('status', "{$deletedName} was removed from the board workflow."); + } + + private function normalizeColumnPositions(Project $project): void + { + $this->persistOrderedColumns( + $project->boardColumns() + ->get() + ->values(), + ); + } + + private function reorderColumns(Project $project, BoardColumn $movingColumn, int $desiredPosition): void + { + /** @var Collection $columns */ + $columns = $project->boardColumns() + ->whereKeyNot($movingColumn->id) + ->get() + ->values(); + + $insertAt = max(0, min($desiredPosition - 1, $columns->count())); + + $columns->splice($insertAt, 0, [$movingColumn]); + + $this->persistOrderedColumns($columns->values()); + } + + /** + * @param Collection $columns + */ + private function persistOrderedColumns(Collection $columns): void + { + $temporaryOffset = ((int) $columns->max('position')) + $columns->count() + 1; + + $columns->each(function (BoardColumn $column, int $index) use ($temporaryOffset): void { + $column->forceFill([ + 'position' => $temporaryOffset + $index, + ])->saveQuietly(); + }); + + $columns->each(function (BoardColumn $column, int $index): void { + $column->forceFill([ + 'position' => $index + 1, + ])->saveQuietly(); + }); + } +} diff --git a/app/Http/Requests/StoreBoardColumnRequest.php b/app/Http/Requests/StoreBoardColumnRequest.php new file mode 100644 index 0000000..29e5a0b --- /dev/null +++ b/app/Http/Requests/StoreBoardColumnRequest.php @@ -0,0 +1,41 @@ +user() !== null; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'name' => ['required', 'string', 'max:255'], + 'position' => ['nullable', 'integer', 'min:1'], + ]; + } + + public function position(): ?int + { + $position = $this->validated('position'); + + if ($position === null) { + return null; + } + + return (int) $position; + } +} diff --git a/app/Http/Requests/UpdateBoardColumnRequest.php b/app/Http/Requests/UpdateBoardColumnRequest.php new file mode 100644 index 0000000..22f0520 --- /dev/null +++ b/app/Http/Requests/UpdateBoardColumnRequest.php @@ -0,0 +1,35 @@ +user() !== null; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'name' => ['required', 'string', 'max:255'], + 'position' => ['required', 'integer', 'min:1'], + ]; + } + + public function position(): int + { + return (int) $this->validated('position'); + } +} diff --git a/app/Models/BoardColumn.php b/app/Models/BoardColumn.php new file mode 100644 index 0000000..218d4c1 --- /dev/null +++ b/app/Models/BoardColumn.php @@ -0,0 +1,21 @@ + */ + use HasFactory; + + public function project(): BelongsTo + { + return $this->belongsTo(Project::class); + } +} diff --git a/app/Models/Project.php b/app/Models/Project.php index aee2442..5bca7f8 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; #[Fillable(['name', 'key'])] @@ -21,4 +22,10 @@ class Project extends Model set: fn (string $value): string => Str::upper(trim($value)), ); } + + public function boardColumns(): HasMany + { + return $this->hasMany(BoardColumn::class) + ->orderBy('position'); + } } diff --git a/database/factories/BoardColumnFactory.php b/database/factories/BoardColumnFactory.php new file mode 100644 index 0000000..461c0e7 --- /dev/null +++ b/database/factories/BoardColumnFactory.php @@ -0,0 +1,27 @@ + + */ +class BoardColumnFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->unique()->words(2, true), + 'position' => 1, + 'project_id' => Project::factory(), + ]; + } +} diff --git a/database/migrations/2026_03_25_002100_create_board_columns_table.php b/database/migrations/2026_03_25_002100_create_board_columns_table.php new file mode 100644 index 0000000..6ce289e --- /dev/null +++ b/database/migrations/2026_03_25_002100_create_board_columns_table.php @@ -0,0 +1,32 @@ +id(); + $table->foreignId('project_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->unsignedInteger('position'); + $table->timestamps(); + + $table->unique(['project_id', 'position']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('board_columns'); + } +}; diff --git a/database/seeders/BoardColumnSeeder.php b/database/seeders/BoardColumnSeeder.php new file mode 100644 index 0000000..a6c376e --- /dev/null +++ b/database/seeders/BoardColumnSeeder.php @@ -0,0 +1,31 @@ +orderBy('id') + ->get() + ->each(function (Project $project): void { + BoardColumn::factory() + ->count(3) + ->sequence( + ['name' => 'Todo', 'position' => 1], + ['name' => 'In Progress', 'position' => 2], + ['name' => 'Done', 'position' => 3], + ) + ->for($project) + ->create(); + }); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index f92aaf9..448c323 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,6 +15,7 @@ class DatabaseSeeder extends Seeder $this->call([ UserSeeder::class, ProjectSeeder::class, + BoardColumnSeeder::class, TeamSeeder::class, ProjectAccessSeeder::class, ]); diff --git a/resources/js/pages/projects/Show.vue b/resources/js/pages/projects/Show.vue index 62cacbf..e8114b2 100644 --- a/resources/js/pages/projects/Show.vue +++ b/resources/js/pages/projects/Show.vue @@ -13,6 +13,7 @@ import { } from '@/components/ui/card'; import AppLayout from '@/layouts/AppLayout.vue'; import { access, index, show } from '@/routes/projects'; +import { board as boardSettings } from '@/routes/projects/settings'; import type { BreadcrumbItem, ProjectShowPageProps } from '@/types'; const props = defineProps(); @@ -73,8 +74,14 @@ const projectAreas = [ -
+
+ +
diff --git a/resources/js/pages/projects/settings/Board.vue b/resources/js/pages/projects/settings/Board.vue new file mode 100644 index 0000000..70d71d3 --- /dev/null +++ b/resources/js/pages/projects/settings/Board.vue @@ -0,0 +1,226 @@ + + + diff --git a/resources/js/types/models/board-column-model.ts b/resources/js/types/models/board-column-model.ts new file mode 100644 index 0000000..a4bb179 --- /dev/null +++ b/resources/js/types/models/board-column-model.ts @@ -0,0 +1,9 @@ +export type BoardColumnModel = { + id: number; + name: string; + position: number; + project_id: number; + created_at: string; + updated_at: string; + [key: string]: unknown; +}; diff --git a/resources/js/types/page-props.ts b/resources/js/types/page-props.ts index 6b82106..3b283a0 100644 --- a/resources/js/types/page-props.ts +++ b/resources/js/types/page-props.ts @@ -1,3 +1,4 @@ +import type { BoardColumnModel } from '@/types/models/board-column-model'; import type { ProjectModel } from '@/types/models/project-model'; import type { TeamModel } from '@/types/models/team-model'; import type { UserModel } from '@/types/models/user-model'; @@ -36,3 +37,9 @@ export type TeamsIndexPageProps = { teams: TeamModel[]; users: UserModel[]; }; + +export type ProjectBoardSettingsPageProps = { + boardColumns: BoardColumnModel[]; + project: ProjectModel; + status?: string | null; +}; diff --git a/routes/web.php b/routes/web.php index 9a95f6a..f044262 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ group(function () { ->name('projects.permissions.users.update'); Route::patch('projects/{project}/permissions/teams/{team}', [ProjectController::class, 'updateTeamPermissions']) ->name('projects.permissions.teams.update'); + + Route::scopeBindings()->group(function (): void { + Route::get('projects/{project}/settings/board', [ProjectBoardSettingsController::class, 'show']) + ->name('projects.settings.board'); + Route::post('projects/{project}/settings/board/columns', [ProjectBoardSettingsController::class, 'store']) + ->name('projects.settings.board.columns.store'); + Route::patch('projects/{project}/settings/board/columns/{boardColumn}', [ProjectBoardSettingsController::class, 'update']) + ->name('projects.settings.board.columns.update'); + Route::delete('projects/{project}/settings/board/columns/{boardColumn}', [ProjectBoardSettingsController::class, 'destroy']) + ->name('projects.settings.board.columns.destroy'); + }); }); Route::middleware(['auth', 'verified', 'can:access-admin']) diff --git a/tests/Feature/Models/BoardColumnTest.php b/tests/Feature/Models/BoardColumnTest.php new file mode 100644 index 0000000..0304359 --- /dev/null +++ b/tests/Feature/Models/BoardColumnTest.php @@ -0,0 +1,83 @@ +create(); + + $this->assertNotNull($boardColumn->project); + $this->assertSame(1, $boardColumn->position); + } + + /** + * Ensure projects expose board columns ordered by position. + */ + public function test_project_board_columns_are_returned_in_position_order(): void + { + $project = Project::factory()->create(); + + BoardColumn::factory()->for($project)->create([ + 'name' => 'Done', + 'position' => 3, + ]); + BoardColumn::factory()->for($project)->create([ + 'name' => 'Todo', + 'position' => 1, + ]); + BoardColumn::factory()->for($project)->create([ + 'name' => 'In Progress', + 'position' => 2, + ]); + + $this->assertSame( + ['Todo', 'In Progress', 'Done'], + $project->fresh()->boardColumns->pluck('name')->all(), + ); + } + + /** + * Ensure the board column seeder creates starter workflow columns for seeded projects. + */ + public function test_board_column_seeder_creates_default_columns_for_projects(): void + { + $this->seed([ + ProjectSeeder::class, + BoardColumnSeeder::class, + ]); + + $coreProject = Project::query()->where('key', 'CORE')->firstOrFail(); + + $this->assertDatabaseHas('board_columns', [ + 'project_id' => $coreProject->id, + 'name' => 'Todo', + 'position' => 1, + ]); + + $this->assertDatabaseHas('board_columns', [ + 'project_id' => $coreProject->id, + 'name' => 'In Progress', + 'position' => 2, + ]); + + $this->assertDatabaseHas('board_columns', [ + 'project_id' => $coreProject->id, + 'name' => 'Done', + 'position' => 3, + ]); + } +} diff --git a/tests/Feature/Models/ProjectTest.php b/tests/Feature/Models/ProjectTest.php index 13e0142..8576079 100644 --- a/tests/Feature/Models/ProjectTest.php +++ b/tests/Feature/Models/ProjectTest.php @@ -2,7 +2,9 @@ namespace Tests\Feature\Models; +use App\Models\BoardColumn; use App\Models\Project; +use Database\Seeders\BoardColumnSeeder; use Database\Seeders\ProjectSeeder; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; @@ -45,4 +47,49 @@ class ProjectTest extends TestCase 'key' => 'OPS', ]); } + + /** + * Ensure projects expose their board columns in the configured order. + */ + public function test_projects_have_an_ordered_board_columns_relationship(): void + { + $project = Project::factory()->create(); + + BoardColumn::factory()->for($project)->create([ + 'name' => 'Done', + 'position' => 3, + ]); + BoardColumn::factory()->for($project)->create([ + 'name' => 'Todo', + 'position' => 1, + ]); + BoardColumn::factory()->for($project)->create([ + 'name' => 'In Progress', + 'position' => 2, + ]); + + $this->assertSame( + ['Todo', 'In Progress', 'Done'], + $project->fresh()->boardColumns->pluck('name')->all(), + ); + } + + /** + * Ensure the default database seeding can include project board columns. + */ + public function test_board_column_seeder_adds_columns_to_seeded_projects(): void + { + $this->seed([ + ProjectSeeder::class, + BoardColumnSeeder::class, + ]); + + $coreProject = Project::query()->where('key', 'CORE')->firstOrFail(); + + $this->assertDatabaseHas('board_columns', [ + 'project_id' => $coreProject->id, + 'name' => 'Todo', + 'position' => 1, + ]); + } } diff --git a/tests/Feature/Projects/ProjectBoardSettingsControllerTest.php b/tests/Feature/Projects/ProjectBoardSettingsControllerTest.php new file mode 100644 index 0000000..91220fe --- /dev/null +++ b/tests/Feature/Projects/ProjectBoardSettingsControllerTest.php @@ -0,0 +1,158 @@ +create(); + $project = Project::factory()->create([ + 'key' => 'CORE', + ]); + BoardColumn::factory()->for($project)->create([ + 'name' => 'Todo', + 'position' => 1, + ]); + + app(ProjectPermissionService::class)->syncUserPermissions($project, $user, ['edit']); + + $this->actingAs($user) + ->get(route('projects.settings.board', $project)) + ->assertOk() + ->assertInertia(fn (Assert $page) => $page + ->component('projects/settings/Board') + ->where('project.id', $project->id) + ->where('boardColumns.0.name', 'Todo'), + ); + } + + /** + * Ensure users without edit permission cannot view board settings. + */ + public function test_users_without_edit_permission_cannot_view_board_settings(): void + { + $user = User::factory()->create(); + $project = Project::factory()->create(); + + $this->actingAs($user) + ->get(route('projects.settings.board', $project)) + ->assertForbidden(); + } + + /** + * Ensure authorized users can create board columns. + */ + public function test_users_with_edit_permission_can_create_board_columns(): void + { + $user = User::factory()->create(); + $project = Project::factory()->create([ + 'key' => 'CORE', + ]); + + app(ProjectPermissionService::class)->syncUserPermissions($project, $user, ['edit']); + + $this->actingAs($user) + ->post(route('projects.settings.board.columns.store', $project), [ + 'name' => 'In Review', + ]) + ->assertRedirect(route('projects.settings.board', $project)) + ->assertSessionHas('status', 'In Review was added to the board workflow.'); + + $this->assertDatabaseHas('board_columns', [ + 'project_id' => $project->id, + 'name' => 'In Review', + 'position' => 1, + ]); + } + + /** + * Ensure authorized users can rename and reorder board columns. + */ + public function test_users_with_edit_permission_can_update_and_reorder_board_columns(): void + { + $user = User::factory()->create(); + $project = Project::factory()->create(); + $firstColumn = BoardColumn::factory()->for($project)->create([ + 'name' => 'Todo', + 'position' => 1, + ]); + $secondColumn = BoardColumn::factory()->for($project)->create([ + 'name' => 'In Progress', + 'position' => 2, + ]); + $thirdColumn = BoardColumn::factory()->for($project)->create([ + 'name' => 'Done', + 'position' => 3, + ]); + + app(ProjectPermissionService::class)->syncUserPermissions($project, $user, ['edit']); + + $this->actingAs($user) + ->patch(route('projects.settings.board.columns.update', [$project, $thirdColumn]), [ + 'name' => 'Ready for QA', + 'position' => 1, + ]) + ->assertRedirect(route('projects.settings.board', $project)) + ->assertSessionHas('status', 'Ready for QA was updated.'); + + $firstColumn->refresh(); + $secondColumn->refresh(); + $thirdColumn->refresh(); + + $this->assertSame(2, $firstColumn->position); + $this->assertSame(3, $secondColumn->position); + $this->assertSame(1, $thirdColumn->position); + $this->assertSame('Ready for QA', $thirdColumn->name); + } + + /** + * Ensure deleting a column normalizes the remaining order. + */ + public function test_deleting_a_board_column_normalizes_remaining_positions(): void + { + $user = User::factory()->create(); + $project = Project::factory()->create(); + $firstColumn = BoardColumn::factory()->for($project)->create([ + 'name' => 'Todo', + 'position' => 1, + ]); + $secondColumn = BoardColumn::factory()->for($project)->create([ + 'name' => 'In Progress', + 'position' => 2, + ]); + $thirdColumn = BoardColumn::factory()->for($project)->create([ + 'name' => 'Done', + 'position' => 3, + ]); + + app(ProjectPermissionService::class)->syncUserPermissions($project, $user, ['edit']); + + $this->actingAs($user) + ->delete(route('projects.settings.board.columns.destroy', [$project, $secondColumn])) + ->assertRedirect(route('projects.settings.board', $project)) + ->assertSessionHas('status', 'In Progress was removed from the board workflow.'); + + $firstColumn->refresh(); + $thirdColumn->refresh(); + + $this->assertSame(1, $firstColumn->position); + $this->assertSame(2, $thirdColumn->position); + $this->assertDatabaseMissing('board_columns', [ + 'id' => $secondColumn->id, + ]); + } +} -- 2.54.0 From 23954e9653707860de7542356a54e603907b1bb0 Mon Sep 17 00:00:00 2001 From: Twyco Date: Thu, 26 Mar 2026 21:52:03 +0100 Subject: [PATCH 2/2] small codestyle fixes --- .../ProjectBoardSettingsController.php | 15 +++++++++------ app/Http/Requests/StoreBoardColumnRequest.php | 11 ----------- app/Http/Requests/UpdateBoardColumnRequest.php | 5 ----- resources/js/types/models/board-column-model.ts | 1 - 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/ProjectBoardSettingsController.php b/app/Http/Controllers/ProjectBoardSettingsController.php index ccb9e1a..b6aca5b 100644 --- a/app/Http/Controllers/ProjectBoardSettingsController.php +++ b/app/Http/Controllers/ProjectBoardSettingsController.php @@ -9,6 +9,7 @@ use App\Models\BoardColumn; use App\Models\Project; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Inertia\Inertia; @@ -42,12 +43,13 @@ class ProjectBoardSettingsController extends Controller $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), 403, ); + $validated = $request->validated(); - $desiredPosition = $request->position() ?? $project->boardColumns()->count() + 1; + $desiredPosition = Arr::get($validated, 'position') ?? $project->boardColumns()->count() + 1; - $boardColumn = DB::transaction(function () use ($project, $request, $desiredPosition): BoardColumn { + $boardColumn = DB::transaction(function () use ($project, $validated, $desiredPosition): BoardColumn { $boardColumn = $project->boardColumns()->create([ - 'name' => $request->validated('name'), + 'name' => Arr::get($validated, 'name'), 'position' => $project->boardColumns()->count() + 1, ]); @@ -69,13 +71,14 @@ class ProjectBoardSettingsController extends Controller $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), 403, ); + $validated = $request->validated(); - DB::transaction(function () use ($boardColumn, $project, $request): void { + DB::transaction(function () use ($boardColumn, $project, $validated): void { $boardColumn->update([ - 'name' => $request->validated('name'), + 'name' => Arr::get($validated, 'name'), ]); - $this->reorderColumns($project, $boardColumn, $request->position()); + $this->reorderColumns($project, $boardColumn, Arr::get($validated, 'position')); }); return to_route('projects.settings.board', $project) diff --git a/app/Http/Requests/StoreBoardColumnRequest.php b/app/Http/Requests/StoreBoardColumnRequest.php index 29e5a0b..212bbf2 100644 --- a/app/Http/Requests/StoreBoardColumnRequest.php +++ b/app/Http/Requests/StoreBoardColumnRequest.php @@ -27,15 +27,4 @@ class StoreBoardColumnRequest extends FormRequest 'position' => ['nullable', 'integer', 'min:1'], ]; } - - public function position(): ?int - { - $position = $this->validated('position'); - - if ($position === null) { - return null; - } - - return (int) $position; - } } diff --git a/app/Http/Requests/UpdateBoardColumnRequest.php b/app/Http/Requests/UpdateBoardColumnRequest.php index 22f0520..5de51c8 100644 --- a/app/Http/Requests/UpdateBoardColumnRequest.php +++ b/app/Http/Requests/UpdateBoardColumnRequest.php @@ -27,9 +27,4 @@ class UpdateBoardColumnRequest extends FormRequest 'position' => ['required', 'integer', 'min:1'], ]; } - - public function position(): int - { - return (int) $this->validated('position'); - } } diff --git a/resources/js/types/models/board-column-model.ts b/resources/js/types/models/board-column-model.ts index a4bb179..52b8f69 100644 --- a/resources/js/types/models/board-column-model.ts +++ b/resources/js/types/models/board-column-model.ts @@ -5,5 +5,4 @@ export type BoardColumnModel = { project_id: number; created_at: string; updated_at: string; - [key: string]: unknown; }; -- 2.54.0