diff --git a/README.md b/README.md index 71cceb3..d4ded6f 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,7 @@ When creating a schedule, the user selects: * The start date * The target completion date -Attainly then distributes the selected elements evenly across the available -days. When an uneven schedule has more than one assignment per day, the user -can place the consecutive heavier days at the start, middle, or end of the -schedule. +Attainly then distributes the selected elements evenly across the available days. For example, a user could choose to schedule: diff --git a/backend/app/Http/Controllers/ScheduleController.php b/backend/app/Http/Controllers/ScheduleController.php index c1f8d12..33a6316 100644 --- a/backend/app/Http/Controllers/ScheduleController.php +++ b/backend/app/Http/Controllers/ScheduleController.php @@ -44,9 +44,6 @@ class ScheduleController extends Controller levelId: $input->integer('levelId'), startDate: $input->string('startDate'), targetDate: $input->string('targetDate'), - workloadPlacement: $input->string( - 'workloadPlacement', - ), ), ); } catch (BadRequestException $exception) { diff --git a/backend/app/Schedule/EvenDistributionScheduler.php b/backend/app/Schedule/EvenDistributionScheduler.php deleted file mode 100644 index e19caf9..0000000 --- a/backend/app/Schedule/EvenDistributionScheduler.php +++ /dev/null @@ -1,114 +0,0 @@ - - */ - public function scheduledDates( - int $assignmentCount, - DateTimeImmutable $startDate, - DateTimeImmutable $targetDate, - WorkloadPlacement $workloadPlacement, - ): array { - $differenceInDays = $startDate->diff($targetDate)->days; - $dayCount = $differenceInDays + 1; - - if ($assignmentCount < $dayCount) { - return $this->sparseDates( - assignmentCount: $assignmentCount, - dayCount: $dayCount, - startDate: $startDate, - ); - } - - return $this->dailyDates( - assignmentCount: $assignmentCount, - dayCount: $dayCount, - startDate: $startDate, - workloadPlacement: $workloadPlacement, - ); - } - - /** - * @return list - */ - private function sparseDates( - int $assignmentCount, - int $dayCount, - DateTimeImmutable $startDate, - ): array { - if ($assignmentCount === 1) { - return [$startDate]; - } - - $dates = []; - for ($assignmentIndex = 0; - $assignmentIndex < $assignmentCount; - $assignmentIndex++ - ) { - $scaledIndex = $assignmentIndex * ($dayCount - 1) - / ($assignmentCount - 1); - $dayIndex = (int) floor($scaledIndex + 0.5); - $dates[] = $startDate->modify("+{$dayIndex} days"); - } - - return $dates; - } - - /** - * @return list - */ - private function dailyDates( - int $assignmentCount, - int $dayCount, - DateTimeImmutable $startDate, - WorkloadPlacement $workloadPlacement, - ): array { - $assignmentsPerDay = intdiv($assignmentCount, $dayCount); - $heavierDayCount = $assignmentCount % $dayCount; - $heavierBlockStart = $this->heavierBlockStart( - dayCount: $dayCount, - heavierDayCount: $heavierDayCount, - workloadPlacement: $workloadPlacement, - ); - $dates = []; - - for ($dayIndex = 0; $dayIndex < $dayCount; $dayIndex++) { - $assignmentCountForDay = $assignmentsPerDay; - if ( - $dayIndex >= $heavierBlockStart - && $dayIndex < $heavierBlockStart + $heavierDayCount - ) { - $assignmentCountForDay++; - } - - $date = $startDate->modify("+{$dayIndex} days"); - for ($index = 0; $index < $assignmentCountForDay; $index++) { - $dates[] = $date; - } - } - - return $dates; - } - - private function heavierBlockStart( - int $dayCount, - int $heavierDayCount, - WorkloadPlacement $workloadPlacement, - ): int { - if ($workloadPlacement === WorkloadPlacement::Start) { - return 0; - } - - if ($workloadPlacement === WorkloadPlacement::End) { - return $dayCount - $heavierDayCount; - } - - return intdiv($dayCount - $heavierDayCount, 2); - } -} diff --git a/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php b/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php index 7c02c9c..fb8635e 100644 --- a/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php +++ b/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php @@ -8,10 +8,8 @@ use App\Exceptions\BadRequestException; use App\Exceptions\NotFoundException; use App\Schedule\CreateScheduleAssignmentDto; use App\Schedule\CreateScheduleDto; -use App\Schedule\EvenDistributionScheduler; use App\Schedule\Schedule; use App\Schedule\ScheduleRepository; -use App\Schedule\WorkloadPlacement; use App\Set\Set; use App\Set\SetLevelRepository; use App\Set\SetRepository; @@ -25,7 +23,6 @@ class CreateSchedule private SetLevelRepository $setLevelRepository, private ElementRepository $elementRepository, private ScheduleRepository $scheduleRepository, - private EvenDistributionScheduler $evenDistributionScheduler, ) {} /** @@ -64,9 +61,6 @@ class CreateSchedule 'targetDate must not be before startDate', ); } - $workloadPlacement = $this->workloadPlacement( - $request->workloadPlacement, - ); $elements = array_values(array_filter( $this->orderedElements($set), @@ -78,15 +72,10 @@ class CreateSchedule throw new BadRequestException('level has no elements'); } - $scheduledDates = $this->evenDistributionScheduler->scheduledDates( - assignmentCount: count($elements), - startDate: $startDate, - targetDate: $targetDate, - workloadPlacement: $workloadPlacement, - ); $assignments = $this->assignments( elements: $elements, - scheduledDates: $scheduledDates, + startDate: $startDate, + targetDate: $targetDate, ); return $this->scheduleRepository->create(new CreateScheduleDto( @@ -155,21 +144,29 @@ class CreateSchedule /** * @param list $elements - * @param list $scheduledDates * @return list */ private function assignments( array $elements, - array $scheduledDates, + DateTimeImmutable $startDate, + DateTimeImmutable $targetDate, ): array { + $differenceInDays = $startDate->diff($targetDate)->days; + $dayCount = $differenceInDays + 1; + $elementCount = count($elements); $assignments = []; foreach ($elements as $index => $element) { + $dayIndex = $this->dayIndex( + elementIndex: $index, + elementCount: $elementCount, + dayCount: $dayCount, + ); $assignments[] = new CreateScheduleAssignmentDto( name: $element->getName(), kind: $element->getKind(), path: $this->elementPath($element), - scheduledDate: $scheduledDates[$index], + scheduledDate: $startDate->modify("+{$dayIndex} days"), position: $index + 1, ); } @@ -193,6 +190,25 @@ class CreateSchedule return $path; } + private function dayIndex( + int $elementIndex, + int $elementCount, + int $dayCount, + ): int { + if ($elementCount === 1 || $dayCount === 1) { + return 0; + } + + if ($elementCount < $dayCount) { + $scaledIndex = $elementIndex * ($dayCount - 1) + / ($elementCount - 1); + + return (int) floor($scaledIndex + 0.5); + } + + return intdiv($elementIndex * $dayCount, $elementCount); + } + /** * @throws BadRequestException */ @@ -221,23 +237,4 @@ class CreateSchedule return $date; } - - /** - * @throws BadRequestException - */ - private function workloadPlacement(?string $value): WorkloadPlacement - { - if ($value === null) { - return WorkloadPlacement::Middle; - } - - $workloadPlacement = WorkloadPlacement::tryFrom($value); - if ($workloadPlacement === null) { - throw new BadRequestException( - 'workloadPlacement must be start, middle, or end', - ); - } - - return $workloadPlacement; - } } diff --git a/backend/app/Schedule/UseCases/CreateSchedule/CreateScheduleRequest.php b/backend/app/Schedule/UseCases/CreateSchedule/CreateScheduleRequest.php index 430b1d8..70ab5db 100644 --- a/backend/app/Schedule/UseCases/CreateSchedule/CreateScheduleRequest.php +++ b/backend/app/Schedule/UseCases/CreateSchedule/CreateScheduleRequest.php @@ -12,6 +12,5 @@ final readonly class CreateScheduleRequest public ?int $levelId, public ?string $startDate, public ?string $targetDate, - public ?string $workloadPlacement, ) {} } diff --git a/backend/app/Schedule/WorkloadPlacement.php b/backend/app/Schedule/WorkloadPlacement.php deleted file mode 100644 index 607f4f6..0000000 --- a/backend/app/Schedule/WorkloadPlacement.php +++ /dev/null @@ -1,10 +0,0 @@ -assertExactJson($response->json()); } - public function test_it_places_heavier_days_at_the_requested_end(): void - { - $user = $this->createUser('reader@example.com'); - $set = $this->createSet($user, 'Course'); - $lessonLevel = $this->createLevel($set, 'lesson'); - $repository = app(ElementRepository::class); - - foreach (range(1, 11) as $number) { - $repository->create(new CreateElementDto( - name: "Lesson {$number}", - level: $lessonLevel, - parentElement: null, - )); - } - $this->createSession($user, 'valid-token'); - - $response = $this->credentialedPost('/api/schedules', [ - 'setId' => $set->getId(), - 'levelId' => $lessonLevel->getId(), - 'startDate' => '2026-08-10', - 'targetDate' => '2026-08-14', - 'workloadPlacement' => 'end', - ])->assertCreated(); - - $days = $response->json('schedule.days'); - $this->assertIsArray($days); - $this->assertSame( - [2, 2, 2, 2, 3], - array_map(function (array $day): int { - return count($day['assignments']); - }, $days), - ); - $this->assertDatabaseCount('schedule_assignments', 11); - $this->assertDatabaseCount('schedules', 1); - } - - public function test_it_rejects_an_unknown_workload_placement(): void - { - $user = $this->createUser('reader@example.com'); - $set = $this->createSet($user, 'Course'); - $lessonLevel = $this->createLevel($set, 'lesson'); - app(ElementRepository::class)->create(new CreateElementDto( - name: 'Lesson 1', - level: $lessonLevel, - parentElement: null, - )); - $this->createSession($user, 'valid-token'); - - $this->credentialedPost('/api/schedules', [ - 'setId' => $set->getId(), - 'levelId' => $lessonLevel->getId(), - 'startDate' => '2026-08-10', - 'targetDate' => '2026-08-14', - 'workloadPlacement' => 'sideways', - ])->assertBadRequest()->assertExactJson([ - 'error' => 'workloadPlacement must be start, middle, or end', - ]); - } - public function test_it_lists_only_the_users_schedules_newest_first(): void { $user = $this->createUser('reader@example.com'); diff --git a/backend/tests/Unit/Schedule/EvenDistributionSchedulerTest.php b/backend/tests/Unit/Schedule/EvenDistributionSchedulerTest.php deleted file mode 100644 index f9e63a7..0000000 --- a/backend/tests/Unit/Schedule/EvenDistributionSchedulerTest.php +++ /dev/null @@ -1,129 +0,0 @@ -value => [3, 2, 2, 2, 2], - WorkloadPlacement::Middle->value => [2, 2, 3, 2, 2], - WorkloadPlacement::End->value => [2, 2, 2, 2, 3], - ]; - - foreach (WorkloadPlacement::cases() as $placement) { - $dates = $scheduler->scheduledDates( - assignmentCount: 11, - startDate: $this->utc('2026-08-10'), - targetDate: $this->utc('2026-08-14'), - workloadPlacement: $placement, - ); - - $this->assertSame( - $expectedCounts[$placement->value], - $this->dailyCounts($dates), - ); - } - } - - public function test_it_keeps_multiple_heavier_days_together(): void - { - $scheduler = new EvenDistributionScheduler; - $expectedCounts = [ - WorkloadPlacement::Start->value => [3, 3, 2, 2, 2], - WorkloadPlacement::Middle->value => [2, 3, 3, 2, 2], - WorkloadPlacement::End->value => [2, 2, 2, 3, 3], - ]; - - foreach (WorkloadPlacement::cases() as $placement) { - $dates = $scheduler->scheduledDates( - assignmentCount: 12, - startDate: $this->utc('2026-08-10'), - targetDate: $this->utc('2026-08-14'), - workloadPlacement: $placement, - ); - - $this->assertSame( - $expectedCounts[$placement->value], - $this->dailyCounts($dates), - ); - } - } - - public function test_it_preserves_sparse_distribution_across_the_full_range(): void - { - $dates = (new EvenDistributionScheduler)->scheduledDates( - assignmentCount: 3, - startDate: $this->utc('2026-08-10'), - targetDate: $this->utc('2026-08-16'), - workloadPlacement: WorkloadPlacement::Middle, - ); - - $this->assertSame( - ['2026-08-10', '2026-08-13', '2026-08-16'], - $this->formattedDates($dates), - ); - } - - public function test_it_distributes_even_and_single_day_schedules(): void - { - $scheduler = new EvenDistributionScheduler; - - $evenDates = $scheduler->scheduledDates( - assignmentCount: 10, - startDate: $this->utc('2026-08-10'), - targetDate: $this->utc('2026-08-14'), - workloadPlacement: WorkloadPlacement::End, - ); - $singleDayDates = $scheduler->scheduledDates( - assignmentCount: 4, - startDate: $this->utc('2026-08-10'), - targetDate: $this->utc('2026-08-10'), - workloadPlacement: WorkloadPlacement::Middle, - ); - - $this->assertSame([2, 2, 2, 2, 2], $this->dailyCounts($evenDates)); - $this->assertSame( - [ - '2026-08-10', - '2026-08-10', - '2026-08-10', - '2026-08-10', - ], - $this->formattedDates($singleDayDates), - ); - } - - /** - * @param list $dates - * @return list - */ - private function dailyCounts(array $dates): array - { - return array_values(array_count_values($this->formattedDates($dates))); - } - - /** - * @param list $dates - * @return list - */ - private function formattedDates(array $dates): array - { - return array_map(function (DateTimeImmutable $date): string { - return $date->format('Y-m-d'); - }, $dates); - } - - private function utc(string $date): DateTimeImmutable - { - return new DateTimeImmutable($date, new DateTimeZone('UTC')); - } -} diff --git a/backend/tests/Unit/Schedule/UseCases/CreateScheduleTest.php b/backend/tests/Unit/Schedule/UseCases/CreateScheduleTest.php index 47cee8d..02b7a83 100644 --- a/backend/tests/Unit/Schedule/UseCases/CreateScheduleTest.php +++ b/backend/tests/Unit/Schedule/UseCases/CreateScheduleTest.php @@ -5,7 +5,6 @@ namespace Tests\Unit\Schedule\UseCases; use App\Element\CreateElementDto; use App\Exceptions\BadRequestException; use App\Exceptions\NotFoundException; -use App\Schedule\EvenDistributionScheduler; use App\Schedule\UseCases\CreateSchedule\CreateSchedule; use App\Schedule\UseCases\CreateSchedule\CreateScheduleRequest; use App\Set\CreateSetDto; @@ -109,14 +108,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, $elementRepository, $scheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: $chapterLevel->getId(), startDate: '2026-08-10', targetDate: '2026-08-12', - workloadPlacement: 'middle', )); $this->assertSame('chapter', $schedule->getElementKind()); @@ -185,14 +182,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, $elementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: $lessonLevel->getId(), startDate: '2026-08-10', targetDate: '2026-08-16', - workloadPlacement: 'middle', )); $this->assertSame( @@ -229,14 +224,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, $elementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: $milestoneLevel->getId(), startDate: '2020-01-01', targetDate: '2030-01-01', - workloadPlacement: 'middle', )); $this->assertSame( @@ -247,102 +240,6 @@ class CreateScheduleTest extends TestCase ); } - public function test_it_defaults_heavier_days_to_the_middle(): void - { - $user = $this->user(); - $setRepository = new FakeSetRepository; - $setLevelRepository = new FakeSetLevelRepository; - $elementRepository = new FakeElementRepository; - $set = $setRepository->create(new CreateSetDto( - name: 'Course', - creator: $user, - )); - $lessonLevel = $this->createLevel( - $setLevelRepository, - $set, - 'lesson', - ); - - foreach (range(1, 6) as $number) { - $elementRepository->create(new CreateElementDto( - name: "Lesson {$number}", - level: $lessonLevel, - parentElement: null, - )); - } - - $schedule = (new CreateSchedule( - $setRepository, - $setLevelRepository, - $elementRepository, - new FakeScheduleRepository, - new EvenDistributionScheduler, - ))->execute(new CreateScheduleRequest( - user: $user, - setId: $set->getId(), - levelId: $lessonLevel->getId(), - startDate: '2026-08-10', - targetDate: '2026-08-13', - workloadPlacement: null, - )); - - $this->assertSame( - [ - '2026-08-10', - '2026-08-11', - '2026-08-11', - '2026-08-12', - '2026-08-12', - '2026-08-13', - ], - array_map(function ($assignment): string { - return $assignment->getScheduledDate()->format('Y-m-d'); - }, $schedule->getAssignments()), - ); - } - - public function test_it_rejects_an_unknown_workload_placement(): void - { - $user = $this->user(); - $setRepository = new FakeSetRepository; - $setLevelRepository = new FakeSetLevelRepository; - $elementRepository = new FakeElementRepository; - $set = $setRepository->create(new CreateSetDto( - name: 'Course', - creator: $user, - )); - $lessonLevel = $this->createLevel( - $setLevelRepository, - $set, - 'lesson', - ); - $elementRepository->create(new CreateElementDto( - name: 'Lesson 1', - level: $lessonLevel, - parentElement: null, - )); - - $this->expectException(BadRequestException::class); - $this->expectExceptionMessage( - 'workloadPlacement must be start, middle, or end', - ); - - (new CreateSchedule( - $setRepository, - $setLevelRepository, - $elementRepository, - new FakeScheduleRepository, - new EvenDistributionScheduler, - ))->execute(new CreateScheduleRequest( - user: $user, - setId: $set->getId(), - levelId: $lessonLevel->getId(), - startDate: '2026-08-10', - targetDate: '2026-08-13', - workloadPlacement: 'sideways', - )); - } - public function test_it_rejects_an_unknown_set(): void { $this->expectException(NotFoundException::class); @@ -353,14 +250,12 @@ class CreateScheduleTest extends TestCase new FakeSetLevelRepository, new FakeElementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $this->user(), setId: 999, levelId: 1, startDate: '2026-08-10', targetDate: '2026-08-12', - workloadPlacement: 'middle', )); } @@ -381,14 +276,12 @@ class CreateScheduleTest extends TestCase new FakeSetLevelRepository, new FakeElementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: null, startDate: '2026-08-10', targetDate: '2026-08-12', - workloadPlacement: 'middle', )); } @@ -419,14 +312,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, new FakeElementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $bible->getId(), levelId: $moduleLevel->getId(), startDate: '2026-08-10', targetDate: '2026-08-12', - workloadPlacement: 'middle', )); } @@ -453,14 +344,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, new FakeElementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: $chapterLevel->getId(), startDate: '2026-08-10', targetDate: '2026-08-12', - workloadPlacement: 'middle', )); } @@ -487,14 +376,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, new FakeElementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: $chapterLevel->getId(), startDate: '2026-02-30', targetDate: '2026-08-12', - workloadPlacement: 'middle', )); } @@ -523,14 +410,12 @@ class CreateScheduleTest extends TestCase $setLevelRepository, new FakeElementRepository, new FakeScheduleRepository, - new EvenDistributionScheduler, ))->execute(new CreateScheduleRequest( user: $user, setId: $set->getId(), levelId: $chapterLevel->getId(), startDate: '2026-08-12', targetDate: '2026-08-10', - workloadPlacement: 'middle', )); } diff --git a/frontend/website/cypress/e2e/set-scheduling.cy.ts b/frontend/website/cypress/e2e/set-scheduling.cy.ts index 25a5b4a..0511405 100644 --- a/frontend/website/cypress/e2e/set-scheduling.cy.ts +++ b/frontend/website/cypress/e2e/set-scheduling.cy.ts @@ -60,13 +60,6 @@ const bibleLayout = { ], } -const overloadedBibleLayout = { - ...bibleLayout, - levels: bibleLayout.levels.map((level) => - level.id === 3 ? { ...level, elementCount: 11 } : level, - ), -} - const scheduleDetail = { schedule: { id: 73, @@ -201,7 +194,6 @@ describe('set scheduling', () => { levelId: 3, startDate: '2026-08-10', targetDate: '2026-08-12', - workloadPlacement: 'middle', }) request.reply({ statusCode: 201, body: scheduleDetail }) }).as('createSchedule') @@ -252,40 +244,6 @@ describe('set scheduling', () => { ) }) - it('places heavier days where the user chooses', () => { - cy.intercept('GET', '**/api/sets/41', { - statusCode: 200, - body: overloadedBibleLayout, - }).as('layout') - cy.intercept('POST', '**/api/schedules', (request) => { - expect(request.body).to.deep.equal({ - setId: 41, - levelId: 3, - startDate: '2026-08-10', - targetDate: '2026-08-14', - workloadPlacement: 'end', - }) - request.reply({ statusCode: 201, body: scheduleDetail }) - }).as('createSchedule') - - cy.visit('/sets/41/schedules/new') - cy.wait('@me') - cy.wait('@layout') - cy.get('[data-workload-placement]').should('not.exist') - - cy.get('#schedule-level').select('3') - cy.get('#schedule-start-date').type('2026-08-10') - cy.get('#schedule-target-date').type('2026-08-14') - - cy.get('[data-workload-placement]').should('be.visible').within(() => { - cy.contains('legend', 'Heavier days').should('be.visible') - cy.get('input[value="middle"]').should('be.checked') - cy.get('input[value="end"]').check() - }) - cy.get('form').submit() - cy.wait('@createSchedule') - }) - it('validates the schedule form before submitting', () => { cy.intercept('GET', '**/api/sets/41', { statusCode: 200, diff --git a/frontend/website/src/stores/schedules.ts b/frontend/website/src/stores/schedules.ts index 3715d0e..825bbfb 100644 --- a/frontend/website/src/stores/schedules.ts +++ b/frontend/website/src/stores/schedules.ts @@ -6,8 +6,6 @@ import { API_BASE } from '@/utils/apiBase' const isoDateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/) -export const workloadPlacementSchema = z.enum(['start', 'middle', 'end']) - export const scheduleSummarySchema = z.object({ id: z.number().int().positive(), set: z.object({ @@ -78,13 +76,11 @@ const errorResponseSchema = z.object({ export type ScheduleSummary = z.infer export type ScheduleDetail = z.infer export type AssignmentForDate = z.infer -export type WorkloadPlacement = z.infer export type CreateScheduleInput = { setId: number levelId: number startDate: string targetDate: string - workloadPlacement: WorkloadPlacement } const LIST_ERROR = "We couldn't load your schedules." diff --git a/frontend/website/src/views/CreateScheduleView.vue b/frontend/website/src/views/CreateScheduleView.vue index 912268d..deea7a2 100644 --- a/frontend/website/src/views/CreateScheduleView.vue +++ b/frontend/website/src/views/CreateScheduleView.vue @@ -5,11 +5,7 @@ import { useRoute, useRouter } from 'vue-router' import { z } from 'zod' import AuthenticatedHeader from '@/components/AuthenticatedHeader.vue' -import { - useSchedulesStore, - workloadPlacementSchema, - type WorkloadPlacement, -} from '@/stores/schedules' +import { useSchedulesStore } from '@/stores/schedules' import { useSetLayoutStore } from '@/stores/setLayout' type ScheduleField = 'levelId' | 'startDate' | 'targetDate' @@ -26,51 +22,18 @@ const form = reactive({ levelId: null as number | null, startDate: '', targetDate: '', - workloadPlacement: 'middle' as WorkloadPlacement, }) const fieldErrors = ref({}) const levels = computed(() => (layout.value?.levels ?? []).filter((level) => level.elementCount > 0), ) -const selectedLevel = computed(() => levels.value.find((level) => level.id === form.levelId)) -const workloadPlacementOptions: Array<{ - value: WorkloadPlacement - label: string -}> = [ - { value: 'start', label: 'At the start' }, - { value: 'middle', label: 'In the middle' }, - { value: 'end', label: 'At the end' }, -] -const showWorkloadPlacement = computed(() => { - if ( - selectedLevel.value === undefined || - form.startDate === '' || - form.targetDate === '' || - form.targetDate < form.startDate - ) { - return false - } - - const startTime = Date.parse(`${form.startDate}T00:00:00Z`) - const targetTime = Date.parse(`${form.targetDate}T00:00:00Z`) - if (Number.isNaN(startTime) || Number.isNaN(targetTime)) { - return false - } - - const millisecondsPerDay = 24 * 60 * 60 * 1000 - const dayCount = Math.round((targetTime - startTime) / millisecondsPerDay) + 1 - const assignmentCount = selectedLevel.value.elementCount - - return assignmentCount > dayCount && assignmentCount % dayCount !== 0 -}) const scheduleFormSchema = z .object({ levelId: z.number('Choose a level to schedule.').int().positive(), startDate: z.string().min(1, 'Choose a start date.'), targetDate: z.string().min(1, 'Choose a target date.'), - workloadPlacement: workloadPlacementSchema, }) .superRefine((value, context) => { if (value.startDate !== '' && value.targetDate !== '' && value.targetDate < value.startDate) { @@ -231,33 +194,6 @@ async function retry(): Promise { -
- Heavier days -

- Some days need one extra assignment. Choose where those days appear in the schedule. -

-
- -
-
-