diff --git a/ai/backend-context.md b/ai/backend-context.md index 3395a52..34729b2 100644 --- a/ai/backend-context.md +++ b/ai/backend-context.md @@ -40,14 +40,11 @@ intentionally omitted here - update this section as entities land. ## Migrations -- This project is in production. Never edit, delete, rename, or reorder an - existing migration file. Every schema change must use a new forward - migration. -- Production migrations must preserve existing data, include any required - backfill, and define a safe rollback. -- Plan schema changes for the deployment order and for compatibility between - the old and new application versions. Use expand/backfill/contract sequencing - when a single compatible migration is not safe. +- This project is not in production. By default, schema changes should update + the relevant create-table migration so migrations describe the current desired + schema from scratch. +- Do not add alter-table or data-backfill migrations unless the user explicitly + asks for production-style migration safety. - Put seed data in seeders, not migrations. ## PHP rules diff --git a/backend/app/Controllers/SetController.php b/backend/app/Controllers/SetController.php index 31b142f..a3c89f6 100644 --- a/backend/app/Controllers/SetController.php +++ b/backend/app/Controllers/SetController.php @@ -11,8 +11,6 @@ use App\Set\UseCases\CreateSetWithRoot\CreateSetWithRoot; use App\Set\UseCases\CreateSetWithRoot\CreateSetWithRootRequest; use App\Set\UseCases\DeleteSet\DeleteSet; use App\Set\UseCases\DeleteSet\DeleteSetRequest; -use App\Set\UseCases\ReorderSets\ReorderSets; -use App\Set\UseCases\ReorderSets\ReorderSetsRequest; use App\Set\UseCases\UpdateSet\UpdateSet; use App\Set\UseCases\UpdateSet\UpdateSetRequest; use App\Shared\Files\Filesystem; @@ -28,34 +26,19 @@ class SetController private CreateSetWithRoot $createSetWithRoot, private UpdateSet $updateSet, private DeleteSet $deleteSet, - private ReorderSets $reorderSets, private Filesystem $filesystem, ) { } public function index(): JsonResponse { - return new JsonResponse([ - 'sets' => $this->buildSetPayloads( - $this->setRepository->getAll(), - ), - ], 200); - } - - public function reorder(Request $request): JsonResponse - { - try { - $sets = $this->reorderSets->execute(new ReorderSetsRequest( - setIds: $this->intArrayInput($request, 'setIds'), - )); - } catch (BadRequestException $exception) { - return new JsonResponse([ - 'error' => $exception->getMessage(), - ], 400); + $sets = []; + foreach ($this->setRepository->getAll() as $set) { + $sets[] = $this->buildSetPayload($set); } return new JsonResponse([ - 'sets' => $this->buildSetPayloads($sets), + 'sets' => $sets, ], 200); } @@ -158,58 +141,6 @@ class SetController ]; } - /** - * @param DomainSet[] $sets - * @return array - */ - private function buildSetPayloads(array $sets): array - { - $setPayloads = []; - foreach ($sets as $set) { - $setPayloads[] = $this->buildSetPayload($set); - } - - return $setPayloads; - } - - /** - * @return int[]|null - */ - private function intArrayInput(Request $request, string $key): ?array - { - if (! $request->exists($key)) { - return null; - } - - $value = $request->input($key); - if (! is_array($value)) { - return null; - } - - $integerValues = []; - foreach ($value as $item) { - if (is_int($item)) { - $integerValues[] = $item; - continue; - } - - if (is_string($item) && ctype_digit($item)) { - $integerValues[] = (int) $item; - continue; - } - - return null; - } - - return $integerValues; - } - private function stringInput(Request $request, string $key): ?string { if (! $request->exists($key)) { diff --git a/backend/app/Set/EloquentSetRepository.php b/backend/app/Set/EloquentSetRepository.php index 08fce3f..be7ac1d 100644 --- a/backend/app/Set/EloquentSetRepository.php +++ b/backend/app/Set/EloquentSetRepository.php @@ -3,7 +3,6 @@ namespace App\Set; use DomainException; -use Illuminate\Support\Facades\DB; class EloquentSetRepository implements SetRepository { @@ -13,7 +12,6 @@ class EloquentSetRepository implements SetRepository 'name' => $dto->name, 'description' => $dto->description, 'icon_image_url' => $dto->iconImageUrl, - 'sort_order' => $this->nextSortOrder(), ]); return $this->toDomain($model); @@ -57,7 +55,7 @@ class EloquentSetRepository implements SetRepository public function getAll(): array { - $models = SetModel::orderBy('sort_order')->orderBy('id')->get(); + $models = SetModel::orderBy('id')->get(); $sets = []; foreach ($models as $model) { $sets[] = $this->toDomain($model); @@ -66,30 +64,6 @@ class EloquentSetRepository implements SetRepository return $sets; } - public function reorder(array $setIds): array - { - DB::transaction(function () use ($setIds): void { - $sortOrder = 1; - foreach ($setIds as $setId) { - SetModel::where('id', $setId) - ->update(['sort_order' => $sortOrder]); - $sortOrder++; - } - }); - - return $this->getAll(); - } - - private function nextSortOrder(): int - { - $currentMaxSortOrder = SetModel::max('sort_order'); - if ($currentMaxSortOrder === null) { - return 1; - } - - return (int) $currentMaxSortOrder + 1; - } - private function toDomain(SetModel $model): Set { return new Set( diff --git a/backend/app/Set/SetModel.php b/backend/app/Set/SetModel.php index 0422ee8..d80a6df 100644 --- a/backend/app/Set/SetModel.php +++ b/backend/app/Set/SetModel.php @@ -10,14 +10,12 @@ use Illuminate\Database\Eloquent\Model; * @property string $name * @property string $description * @property string $icon_image_url - * @property int $sort_order * * @method static Builder|SetModel newModelQuery() * @method static Builder|SetModel newQuery() * @method static Builder|SetModel query() * @method static Builder|SetModel whereId($value) * @method static Builder|SetModel whereName($value) - * @method static Builder|SetModel whereSortOrder($value) * * @mixin \Eloquent */ @@ -27,14 +25,5 @@ class SetModel extends Model public $timestamps = false; - protected $fillable = [ - 'name', - 'description', - 'icon_image_url', - 'sort_order', - ]; - - protected $casts = [ - 'sort_order' => 'integer', - ]; + protected $fillable = ['name', 'description', 'icon_image_url']; } diff --git a/backend/app/Set/SetRepository.php b/backend/app/Set/SetRepository.php index bffbb02..79d9dde 100644 --- a/backend/app/Set/SetRepository.php +++ b/backend/app/Set/SetRepository.php @@ -16,10 +16,4 @@ interface SetRepository * @return Set[] */ public function getAll(): array; - - /** - * @param int[] $setIds - * @return Set[] - */ - public function reorder(array $setIds): array; } diff --git a/backend/app/Set/UseCases/ReorderSets/ReorderSets.php b/backend/app/Set/UseCases/ReorderSets/ReorderSets.php deleted file mode 100644 index 1937519..0000000 --- a/backend/app/Set/UseCases/ReorderSets/ReorderSets.php +++ /dev/null @@ -1,128 +0,0 @@ -setIds === null) { - throw new BadRequestException('setIds is required'); - } - - $setIds = $this->validatedSetIds($request->setIds); - $existingSetIds = $this->setIds($this->setRepository->getAll()); - - $this->validateNoDuplicateIds($setIds); - $this->validateAllIdsAreSets($setIds, $existingSetIds); - $this->validateEverySetWasSubmitted($setIds, $existingSetIds); - - return $this->setRepository->reorder($setIds); - } - - /** - * @param mixed[] $setIds - * @return int[] - * @throws BadRequestException - */ - private function validatedSetIds(array $setIds): array - { - $validatedSetIds = []; - foreach ($setIds as $setId) { - if (! is_int($setId)) { - throw new BadRequestException( - 'setIds must contain integers', - ); - } - - $validatedSetIds[] = $setId; - } - - return $validatedSetIds; - } - - /** - * @param int[] $setIds - * @throws BadRequestException - */ - private function validateNoDuplicateIds(array $setIds): void - { - $seenSetIds = []; - foreach ($setIds as $setId) { - if (isset($seenSetIds[$setId])) { - throw new BadRequestException( - 'Set order contains duplicate ids', - ); - } - - $seenSetIds[$setId] = true; - } - } - - /** - * @param int[] $setIds - * @param int[] $existingSetIds - * @throws BadRequestException - */ - private function validateAllIdsAreSets( - array $setIds, - array $existingSetIds, - ): void { - $existingSetIdsById = []; - foreach ($existingSetIds as $existingSetId) { - $existingSetIdsById[$existingSetId] = true; - } - - foreach ($setIds as $setId) { - if (! isset($existingSetIdsById[$setId])) { - throw new BadRequestException( - 'Set order contains invalid set', - ); - } - } - } - - /** - * @param int[] $setIds - * @param int[] $existingSetIds - * @throws BadRequestException - */ - private function validateEverySetWasSubmitted( - array $setIds, - array $existingSetIds, - ): void { - if (count($setIds) === count($existingSetIds)) { - return; - } - - throw new BadRequestException( - 'Set order must include every set', - ); - } - - /** - * @param Set[] $sets - * @return int[] - */ - private function setIds(array $sets): array - { - $setIds = []; - foreach ($sets as $set) { - $setIds[] = $set->getId(); - } - - return $setIds; - } -} diff --git a/backend/app/Set/UseCases/ReorderSets/ReorderSetsRequest.php b/backend/app/Set/UseCases/ReorderSets/ReorderSetsRequest.php deleted file mode 100644 index 86dfe00..0000000 --- a/backend/app/Set/UseCases/ReorderSets/ReorderSetsRequest.php +++ /dev/null @@ -1,13 +0,0 @@ -unsignedInteger('sort_order')->nullable(); - }); - - $setIds = DB::table('sets')->orderBy('id')->pluck('id'); - $sortOrder = 1; - foreach ($setIds as $setId) { - DB::table('sets') - ->where('id', $setId) - ->update(['sort_order' => $sortOrder]); - $sortOrder++; - } - - Schema::table('sets', function (Blueprint $table): void { - $table->unsignedInteger('sort_order') - ->nullable(false) - ->change(); - }); - } - - public function down(): void - { - Schema::table('sets', function (Blueprint $table): void { - $table->dropColumn('sort_order'); - }); - } -}; diff --git a/backend/routes/api.php b/backend/routes/api.php index 0163757..12f02d8 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -11,8 +11,6 @@ Route::post('/logout', [AuthController::class, 'logout']); Route::get('/me', [AuthController::class, 'me']) ->middleware(AuthMiddleware::class); Route::get('/sets', [SetController::class, 'index']); -Route::put('/sets/order', [SetController::class, 'reorder']) - ->middleware(AuthMiddleware::class); Route::post('/sets', [SetController::class, 'create']) ->middleware(AuthMiddleware::class); Route::post('/sets/{id}/update', [SetController::class, 'update']) diff --git a/backend/tests/Fakes/FakeSetRepository.php b/backend/tests/Fakes/FakeSetRepository.php index 4cced39..f3efc1c 100644 --- a/backend/tests/Fakes/FakeSetRepository.php +++ b/backend/tests/Fakes/FakeSetRepository.php @@ -13,11 +13,6 @@ class FakeSetRepository implements SetRepository */ private array $setsById = []; - /** - * @var array - */ - private array $sortOrdersById = []; - public function create(CreateSetDto $dto): DomainSet { $id = count($this->setsById) + 1; @@ -28,7 +23,6 @@ class FakeSetRepository implements SetRepository iconImageUrl: $dto->iconImageUrl, ); $this->setsById[$id] = $set; - $this->sortOrdersById[$id] = $this->nextSortOrder(); return $set; } @@ -44,7 +38,6 @@ class FakeSetRepository implements SetRepository public function delete(DomainSet $set): void { unset($this->setsById[$set->getId()]); - unset($this->sortOrdersById[$set->getId()]); } public function find(int $id): ?DomainSet @@ -65,35 +58,10 @@ class FakeSetRepository implements SetRepository foreach ($this->setsById as $set) { $sets[] = $this->cloneSet($set); } - usort($sets, function ( - DomainSet $firstSet, - DomainSet $secondSet, - ): int { - $firstSortOrder = $this->sortOrdersById[$firstSet->getId()] - ?? $firstSet->getId(); - $secondSortOrder = $this->sortOrdersById[$secondSet->getId()] - ?? $secondSet->getId(); - if ($firstSortOrder === $secondSortOrder) { - return $firstSet->getId() <=> $secondSet->getId(); - } - - return $firstSortOrder <=> $secondSortOrder; - }); return $sets; } - public function reorder(array $setIds): array - { - $sortOrder = 1; - foreach ($setIds as $setId) { - $this->sortOrdersById[$setId] = $sortOrder; - $sortOrder++; - } - - return $this->getAll(); - } - private function cloneSet(DomainSet $set): DomainSet { return new DomainSet( @@ -103,13 +71,4 @@ class FakeSetRepository implements SetRepository iconImageUrl: $set->getIconImageUrl(), ); } - - private function nextSortOrder(): int - { - if ($this->sortOrdersById === []) { - return 1; - } - - return max($this->sortOrdersById) + 1; - } } diff --git a/backend/tests/Feature/SetOrderingMigrationTest.php b/backend/tests/Feature/SetOrderingMigrationTest.php deleted file mode 100644 index 806b892..0000000 --- a/backend/tests/Feature/SetOrderingMigrationTest.php +++ /dev/null @@ -1,86 +0,0 @@ -runMigrationAgainstLegacySets(); - - $this->assertSame( - [2, 7], - DB::table('sets')->orderBy('sort_order')->pluck('id')->all(), - ); - $this->assertSame( - [1, 2], - DB::table('sets') - ->orderBy('sort_order') - ->pluck('sort_order') - ->all(), - ); - - $this->expectException(QueryException::class); - DB::table('sets')->insert([ - 'id' => 9, - 'name' => 'Unordered Set', - 'description' => 'A set without an explicit position', - 'icon_image_url' => '/assets/unordered.png', - ]); - } - - public function testRollbackRemovesOrderWithoutDeletingSets(): void - { - $migration = $this->runMigrationAgainstLegacySets(); - - $migration->down(); - - $this->assertFalse(Schema::hasColumn('sets', 'sort_order')); - $this->assertSame( - [2, 7], - DB::table('sets')->orderBy('id')->pluck('id')->all(), - ); - } - - private function runMigrationAgainstLegacySets(): object - { - if (Schema::hasColumn('sets', 'sort_order')) { - Schema::table('sets', function (Blueprint $table): void { - $table->dropColumn('sort_order'); - }); - } - - DB::table('sets')->delete(); - DB::table('sets')->insert([ - [ - 'id' => 7, - 'name' => 'Later Set', - 'description' => 'Created later', - 'icon_image_url' => '/assets/later.png', - ], - [ - 'id' => 2, - 'name' => 'Earlier Set', - 'description' => 'Created earlier', - 'icon_image_url' => '/assets/earlier.png', - ], - ]); - - $migration = require database_path(self::MIGRATION_PATH); - $migration->up(); - - return $migration; - } -} diff --git a/backend/tests/Feature/SetsEndpointTest.php b/backend/tests/Feature/SetsEndpointTest.php index d648b40..b2afe90 100644 --- a/backend/tests/Feature/SetsEndpointTest.php +++ b/backend/tests/Feature/SetsEndpointTest.php @@ -73,98 +73,6 @@ class SetsEndpointTest extends TestCase ]); } - public function testReorderSetsRequiresAuthentication(): void - { - $response = $this->putJson('/api/sets/order', [ - 'setIds' => [1, 2], - ]); - - $response->assertUnauthorized(); - $response->assertExactJson([ - 'error' => 'unauthenticated', - ]); - } - - public function testAuthenticatedReorderSetsPersistsPublicOrder(): void - { - $setRepository = app(SetRepository::class); - $firstSet = $setRepository->create(new CreateSetDto( - name: 'First Set', - description: 'First set description', - iconImageUrl: '/assets/first.png', - )); - $secondSet = $setRepository->create(new CreateSetDto( - name: 'Second Set', - description: 'Second set description', - iconImageUrl: '/assets/second.png', - )); - $thirdSet = $setRepository->create(new CreateSetDto( - name: 'Third Set', - description: 'Third set description', - iconImageUrl: '/assets/third.png', - )); - $this->createSession('valid-token'); - - $response = $this->withCredentials() - ->withUnencryptedCookie('auth_token', 'valid-token') - ->putJson('/api/sets/order', [ - 'setIds' => [ - $thirdSet->getId(), - $firstSet->getId(), - $secondSet->getId(), - ], - ]); - - $response->assertOk(); - $response->assertJsonCount(3, 'sets'); - $response->assertJsonPath('sets.0.id', $thirdSet->getId()); - $response->assertJsonPath('sets.1.id', $firstSet->getId()); - $response->assertJsonPath('sets.2.id', $secondSet->getId()); - - $publicResponse = $this->getJson('/api/sets'); - $publicResponse->assertOk(); - $publicResponse->assertJsonPath('sets.0.id', $thirdSet->getId()); - $publicResponse->assertJsonPath('sets.1.id', $firstSet->getId()); - $publicResponse->assertJsonPath('sets.2.id', $secondSet->getId()); - } - - public function testCreatedSetAppendsToSavedOrder(): void - { - $setRepository = app(SetRepository::class); - $firstSet = $setRepository->create(new CreateSetDto( - name: 'First Set', - description: 'First set description', - iconImageUrl: '/assets/first.png', - )); - $secondSet = $setRepository->create(new CreateSetDto( - name: 'Second Set', - description: 'Second set description', - iconImageUrl: '/assets/second.png', - )); - $this->createSession('valid-token'); - $this->withCredentials() - ->withUnencryptedCookie('auth_token', 'valid-token') - ->putJson('/api/sets/order', [ - 'setIds' => [ - $secondSet->getId(), - $firstSet->getId(), - ], - ]) - ->assertOk(); - - $thirdSet = $setRepository->create(new CreateSetDto( - name: 'Third Set', - description: 'Third set description', - iconImageUrl: '/assets/third.png', - )); - - $publicResponse = $this->getJson('/api/sets'); - $publicResponse->assertOk(); - $publicResponse->assertJsonPath('sets.0.id', $secondSet->getId()); - $publicResponse->assertJsonPath('sets.1.id', $firstSet->getId()); - $publicResponse->assertJsonPath('sets.2.id', $thirdSet->getId()); - } - public function testCreateSetRequiresAuthentication(): void { $response = $this->postJson('/api/sets', [ diff --git a/backend/tests/Unit/Set/UseCases/ReorderSetsTest.php b/backend/tests/Unit/Set/UseCases/ReorderSetsTest.php deleted file mode 100644 index e323a72..0000000 --- a/backend/tests/Unit/Set/UseCases/ReorderSetsTest.php +++ /dev/null @@ -1,135 +0,0 @@ -setRepository = new FakeSetRepository(); - $this->reorderSets = new ReorderSets($this->setRepository); - } - - public function testReordersEverySet(): void - { - $firstSet = $this->createSet('First Set'); - $secondSet = $this->createSet('Second Set'); - $thirdSet = $this->createSet('Third Set'); - - $sets = $this->reorderSets->execute(new ReorderSetsRequest( - setIds: [ - $thirdSet->getId(), - $firstSet->getId(), - $secondSet->getId(), - ], - )); - - $expectedSetIds = [ - $thirdSet->getId(), - $firstSet->getId(), - $secondSet->getId(), - ]; - $this->assertSame($expectedSetIds, $this->setIds($sets)); - $this->assertSame( - $expectedSetIds, - $this->setIds($this->setRepository->getAll()), - ); - } - - public function testThrowsWhenSetIdsAreMissing(): void - { - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('setIds is required'); - - $this->reorderSets->execute(new ReorderSetsRequest(setIds: null)); - } - - public function testThrowsWhenSetIdsAreNotIntegers(): void - { - $firstSet = $this->createSet('First Set'); - - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('setIds must contain integers'); - - $this->reorderSets->execute(new ReorderSetsRequest( - setIds: [$firstSet->getId(), 'invalid'], - )); - } - - public function testThrowsWhenSetIdsContainDuplicates(): void - { - $firstSet = $this->createSet('First Set'); - $secondSet = $this->createSet('Second Set'); - - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('Set order contains duplicate ids'); - - $this->reorderSets->execute(new ReorderSetsRequest( - setIds: [ - $firstSet->getId(), - $firstSet->getId(), - $secondSet->getId(), - ], - )); - } - - public function testThrowsWhenSetOrderContainsUnknownSet(): void - { - $firstSet = $this->createSet('First Set'); - - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('Set order contains invalid set'); - - $this->reorderSets->execute(new ReorderSetsRequest( - setIds: [$firstSet->getId(), 999], - )); - } - - public function testThrowsWhenSetOrderOmitsSet(): void - { - $firstSet = $this->createSet('First Set'); - $this->createSet('Second Set'); - - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage('Set order must include every set'); - - $this->reorderSets->execute(new ReorderSetsRequest( - setIds: [$firstSet->getId()], - )); - } - - private function createSet(string $name): DomainSet - { - return $this->setRepository->create(new CreateSetDto( - name: $name, - description: "$name description", - iconImageUrl: "/assets/$name.png", - )); - } - - /** - * @param DomainSet[] $sets - * @return int[] - */ - private function setIds(array $sets): array - { - $setIds = []; - foreach ($sets as $set) { - $setIds[] = $set->getId(); - } - - return $setIds; - } -} diff --git a/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts b/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts index 0573764..2bbb833 100644 --- a/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts +++ b/frontend/rabbi_gerzi/cypress/e2e/media.cy.ts @@ -188,85 +188,6 @@ describe('media page sets', () => { cy.get('[data-cy="media-set-delete"]').should('not.exist') }) - it('reorders sets and persists the public order', () => { - cy.resetDb() - loginAsAdmin() - cy.visit('/media') - cy.intercept('PUT', /\/api\/sets\/order$/).as('reorderSets') - - cy.contains('[data-cy="media-set-card"]', 'Daily Learning') - .within(() => { - cy.get('[data-cy="media-set-move-up"]').click() - }) - cy.wait('@reorderSets') - - cy.get('[data-cy="media-set-order-status"]') - .should('be.visible') - .and('contain.text', 'Set order saved') - cy.get('[data-cy="media-set-card"]') - .eq(0) - .should('contain.text', 'Daily Learning') - .within(() => { - cy.get('[data-cy="media-set-move-up"]').should('be.disabled') - }) - cy.get('[data-cy="media-set-card"]') - .eq(1) - .should('contain.text', 'Baderech HaAvodah') - .within(() => { - cy.get('[data-cy="media-set-move-down"]').should('be.disabled') - }) - - cy.reload() - cy.get('[data-cy="media-set-card"]') - .eq(0) - .should('contain.text', 'Daily Learning') - cy.get('[data-cy="media-set-card"]') - .eq(1) - .should('contain.text', 'Baderech HaAvodah') - - cy.clearCookie('auth_token') - cy.reload() - cy.get('[data-cy="media-set-card"]') - .eq(0) - .should('contain.text', 'Daily Learning') - cy.get('[data-cy="media-set-card"]') - .eq(1) - .should('contain.text', 'Baderech HaAvodah') - cy.get('[data-cy="media-set-move-up"]').should('not.exist') - cy.get('[data-cy="media-set-move-down"]').should('not.exist') - - cy.resetDb() - }) - - it('preserves set order when saving fails', () => { - cy.resetDb() - loginAsAdmin() - cy.visit('/media') - cy.intercept('PUT', /\/api\/sets\/order$/, { - statusCode: 500, - body: { error: 'Unexpected failure' }, - }).as('reorderSets') - - cy.contains('[data-cy="media-set-card"]', 'Daily Learning') - .within(() => { - cy.get('[data-cy="media-set-move-up"]').click() - }) - cy.wait('@reorderSets') - - cy.get('[data-cy="media-set-order-error"]') - .should('be.visible') - .and('contain.text', 'Could not save set order') - cy.get('[data-cy="media-set-order-status"]').should('not.exist') - cy.get('[data-cy="media-set-card"]') - .eq(0) - .should('contain.text', 'Baderech HaAvodah') - cy.get('[data-cy="media-set-card"]') - .eq(1) - .should('contain.text', 'Daily Learning') - - cy.resetDb() - }) - it('creates a set from the logged-in media page modal', () => { loginAsAdmin() cy.visit('/media') diff --git a/frontend/rabbi_gerzi/src/stores/mediaSets.ts b/frontend/rabbi_gerzi/src/stores/mediaSets.ts index f880b76..e669e85 100644 --- a/frontend/rabbi_gerzi/src/stores/mediaSets.ts +++ b/frontend/rabbi_gerzi/src/stores/mediaSets.ts @@ -43,11 +43,9 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { const isCreating = ref(false) const isUpdating = ref(false) const isDeleting = ref(false) - const isReordering = ref(false) const createError = ref(null) const updateError = ref(null) const deleteError = ref(null) - const reorderError = ref(null) async function fetchSets(): Promise { error.value = null @@ -189,43 +187,6 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { } } - async function reorderSets(setIds: number[]): Promise { - reorderError.value = null - isReordering.value = true - - try { - const response = await fetch(`${API_BASE_URL}/api/sets/order`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - credentials: 'include', - body: JSON.stringify({ setIds }), - }) - - if (!response.ok) { - if (response.status === 401) { - reorderError.value = 'Please log in again' - } else if (response.status === 400) { - reorderError.value = await errorMessage( - response, - 'Could not save set order', - ) - } else { - reorderError.value = 'Could not save set order' - } - return false - } - - const data: SetsResponse = await response.json() - sets.value = data.sets - return true - } catch { - reorderError.value = 'Network error - could not save set order' - return false - } finally { - isReordering.value = false - } - } - async function errorMessage( response: Response, fallbackMessage: string, @@ -245,15 +206,12 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { isCreating, isUpdating, isDeleting, - isReordering, createError, updateError, deleteError, - reorderError, fetchSets, createSet, updateSet, deleteSet, - reorderSets, } }) diff --git a/frontend/rabbi_gerzi/src/views/MediaPage.vue b/frontend/rabbi_gerzi/src/views/MediaPage.vue index 7d81276..07f407b 100644 --- a/frontend/rabbi_gerzi/src/views/MediaPage.vue +++ b/frontend/rabbi_gerzi/src/views/MediaPage.vue @@ -3,8 +3,6 @@ import { storeToRefs } from 'pinia' import { computed, onMounted, reactive, ref } from 'vue' import { AlertTriangle as AlertTriangleIcon, - ChevronDown as ChevronDownIcon, - ChevronUp as ChevronUpIcon, Pencil as PencilIcon, Plus as PlusIcon, Trash2 as TrashIcon, @@ -20,8 +18,6 @@ interface CreateSetForm { description: string } -type SetMoveDirection = 'up' | 'down' - const router = useRouter() const authStore = useAuthStore() const mediaSetsStore = useMediaSetsStore() @@ -32,11 +28,9 @@ const { isCreating, isUpdating, isDeleting, - isReordering, createError, updateError, deleteError, - reorderError, } = storeToRefs(mediaSetsStore) const isCreateModalOpen = ref(false) const isEditModalOpen = ref(false) @@ -48,7 +42,6 @@ const localCreateError = ref(null) const localEditError = ref(null) const editingSet = ref(null) const deletingSet = ref(null) -const setOrderStatus = ref(null) const createSetForm = reactive({ name: '', @@ -238,42 +231,6 @@ async function handleDeleteSet(): Promise { deletingSet.value = null } -async function handleMoveSet( - setId: number, - direction: SetMoveDirection, -): Promise { - const currentIndex = sets.value.findIndex((mediaSet) => { - return mediaSet.id === setId - }) - if (currentIndex === -1) { - return - } - - const targetIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1 - if (targetIndex < 0 || targetIndex >= sets.value.length) { - return - } - - const reorderedSets = [...sets.value] - const movingSet = reorderedSets[currentIndex] - const targetSet = reorderedSets[targetIndex] - if (movingSet === undefined || targetSet === undefined) { - return - } - - reorderedSets[currentIndex] = targetSet - reorderedSets[targetIndex] = movingSet - const setIds = reorderedSets.map((mediaSet) => { - return mediaSet.id - }) - - setOrderStatus.value = null - const saved = await mediaSetsStore.reorderSets(setIds) - if (saved) { - setOrderStatus.value = 'Set order saved' - } -} - function openSet(mediaSet: MediaSet): void { if (mediaSet.rootElementId === null) { return @@ -330,30 +287,6 @@ function resetEditSetForm(): void {
-

- {{ setOrderStatus }} -

-

- {{ reorderError }} -

Loading media sets...

-