snapshot schedule source data
This commit is contained in:
parent
14fe2fcb46
commit
f500bd6095
14 changed files with 84 additions and 87 deletions
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Element\Element;
|
|
||||||
use App\Exceptions\BadRequestException;
|
use App\Exceptions\BadRequestException;
|
||||||
use App\Exceptions\NotFoundException;
|
use App\Exceptions\NotFoundException;
|
||||||
use App\Schedule\Schedule;
|
use App\Schedule\Schedule;
|
||||||
|
|
@ -96,13 +95,10 @@ class ScheduleController extends Controller
|
||||||
*/
|
*/
|
||||||
private function summaryPayload(Schedule $schedule): array
|
private function summaryPayload(Schedule $schedule): array
|
||||||
{
|
{
|
||||||
$set = $schedule->getSet();
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $schedule->getId(),
|
'id' => $schedule->getId(),
|
||||||
'set' => [
|
'set' => [
|
||||||
'id' => $set->getId(),
|
'name' => $schedule->getSetName(),
|
||||||
'name' => $set->getName(),
|
|
||||||
],
|
],
|
||||||
'elementKind' => $schedule->getElementKind(),
|
'elementKind' => $schedule->getElementKind(),
|
||||||
'startDate' => $schedule->getStartDate()->format('Y-m-d'),
|
'startDate' => $schedule->getStartDate()->format('Y-m-d'),
|
||||||
|
|
@ -150,8 +146,7 @@ class ScheduleController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{element: array{
|
* @return array{id: int, element: array{
|
||||||
* id: int,
|
|
||||||
* name: string,
|
* name: string,
|
||||||
* kind: string,
|
* kind: string,
|
||||||
* path: list<string>
|
* path: list<string>
|
||||||
|
|
@ -160,34 +155,16 @@ class ScheduleController extends Controller
|
||||||
private function assignmentPayload(
|
private function assignmentPayload(
|
||||||
ScheduleAssignment $assignment,
|
ScheduleAssignment $assignment,
|
||||||
): array {
|
): array {
|
||||||
$element = $assignment->getElement();
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
'id' => $assignment->getId(),
|
||||||
'element' => [
|
'element' => [
|
||||||
'id' => $element->getId(),
|
'name' => $assignment->getName(),
|
||||||
'name' => $element->getName(),
|
'kind' => $assignment->getKind(),
|
||||||
'kind' => $element->getKind(),
|
'path' => $assignment->getPath(),
|
||||||
'path' => $this->elementPath($element),
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return list<string>
|
|
||||||
*/
|
|
||||||
private function elementPath(Element $element): array
|
|
||||||
{
|
|
||||||
$path = [];
|
|
||||||
$currentElement = $element;
|
|
||||||
|
|
||||||
while ($currentElement !== null) {
|
|
||||||
array_unshift($path, $currentElement->getName());
|
|
||||||
$currentElement = $currentElement->getParentElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function user(Request $request): User
|
private function user(Request $request): User
|
||||||
{
|
{
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,17 @@
|
||||||
|
|
||||||
namespace App\Schedule;
|
namespace App\Schedule;
|
||||||
|
|
||||||
use App\Element\Element;
|
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
|
||||||
final readonly class CreateScheduleAssignmentDto
|
final readonly class CreateScheduleAssignmentDto
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param list<string> $path
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public Element $element,
|
public string $name,
|
||||||
|
public string $kind,
|
||||||
|
public array $path,
|
||||||
public DateTimeImmutable $scheduledDate,
|
public DateTimeImmutable $scheduledDate,
|
||||||
public int $position,
|
public int $position,
|
||||||
) {}
|
) {}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Schedule;
|
namespace App\Schedule;
|
||||||
|
|
||||||
use App\Set\Set;
|
|
||||||
use App\User\User;
|
use App\User\User;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
|
||||||
|
|
@ -13,7 +12,7 @@ final readonly class CreateScheduleDto
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public User $user,
|
public User $user,
|
||||||
public Set $set,
|
public string $setName,
|
||||||
public string $elementKind,
|
public string $elementKind,
|
||||||
public DateTimeImmutable $startDate,
|
public DateTimeImmutable $startDate,
|
||||||
public DateTimeImmutable $targetDate,
|
public DateTimeImmutable $targetDate,
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,19 @@
|
||||||
|
|
||||||
namespace App\Schedule;
|
namespace App\Schedule;
|
||||||
|
|
||||||
use App\Element\ElementRepository;
|
|
||||||
use App\Set\SetRepository;
|
|
||||||
use App\User\User;
|
use App\User\User;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use DateTimeZone;
|
use DateTimeZone;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
class EloquentScheduleRepository implements ScheduleRepository
|
class EloquentScheduleRepository implements ScheduleRepository
|
||||||
{
|
{
|
||||||
public function __construct(
|
|
||||||
private SetRepository $setRepository,
|
|
||||||
private ElementRepository $elementRepository,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function create(CreateScheduleDto $dto): Schedule
|
public function create(CreateScheduleDto $dto): Schedule
|
||||||
{
|
{
|
||||||
return DB::transaction(function () use ($dto): Schedule {
|
return DB::transaction(function () use ($dto): Schedule {
|
||||||
$model = ScheduleModel::create([
|
$model = ScheduleModel::create([
|
||||||
'user_id' => $dto->user->getId(),
|
'user_id' => $dto->user->getId(),
|
||||||
'set_id' => $dto->set->getId(),
|
'set_name' => $dto->setName,
|
||||||
'element_kind' => $dto->elementKind,
|
'element_kind' => $dto->elementKind,
|
||||||
'start_date' => $dto->startDate->format('Y-m-d'),
|
'start_date' => $dto->startDate->format('Y-m-d'),
|
||||||
'target_date' => $dto->targetDate->format('Y-m-d'),
|
'target_date' => $dto->targetDate->format('Y-m-d'),
|
||||||
|
|
@ -31,7 +23,9 @@ class EloquentScheduleRepository implements ScheduleRepository
|
||||||
foreach ($dto->assignments as $assignmentDto) {
|
foreach ($dto->assignments as $assignmentDto) {
|
||||||
ScheduleAssignmentModel::create([
|
ScheduleAssignmentModel::create([
|
||||||
'schedule_id' => $model->id,
|
'schedule_id' => $model->id,
|
||||||
'element_id' => $assignmentDto->element->getId(),
|
'element_name' => $assignmentDto->name,
|
||||||
|
'element_kind' => $assignmentDto->kind,
|
||||||
|
'element_path' => $assignmentDto->path,
|
||||||
'scheduled_date' => $assignmentDto->scheduledDate
|
'scheduled_date' => $assignmentDto->scheduledDate
|
||||||
->format('Y-m-d'),
|
->format('Y-m-d'),
|
||||||
'position' => $assignmentDto->position,
|
'position' => $assignmentDto->position,
|
||||||
|
|
@ -69,11 +63,6 @@ class EloquentScheduleRepository implements ScheduleRepository
|
||||||
|
|
||||||
private function toDomain(ScheduleModel $model, User $user): Schedule
|
private function toDomain(ScheduleModel $model, User $user): Schedule
|
||||||
{
|
{
|
||||||
$set = $this->setRepository->find($model->set_id);
|
|
||||||
if ($set === null) {
|
|
||||||
throw new RuntimeException('schedule set not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
$assignmentModels = ScheduleAssignmentModel::query()
|
$assignmentModels = ScheduleAssignmentModel::query()
|
||||||
->where('schedule_id', $model->id)
|
->where('schedule_id', $model->id)
|
||||||
->orderBy('position')
|
->orderBy('position')
|
||||||
|
|
@ -82,16 +71,11 @@ class EloquentScheduleRepository implements ScheduleRepository
|
||||||
$assignments = [];
|
$assignments = [];
|
||||||
|
|
||||||
foreach ($assignmentModels as $assignmentModel) {
|
foreach ($assignmentModels as $assignmentModel) {
|
||||||
$element = $this->elementRepository->find(
|
|
||||||
$assignmentModel->element_id,
|
|
||||||
);
|
|
||||||
if ($element === null) {
|
|
||||||
throw new RuntimeException('schedule element not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
$assignments[] = new ScheduleAssignment(
|
$assignments[] = new ScheduleAssignment(
|
||||||
id: $assignmentModel->id,
|
id: $assignmentModel->id,
|
||||||
element: $element,
|
name: $assignmentModel->element_name,
|
||||||
|
kind: $assignmentModel->element_kind,
|
||||||
|
path: $assignmentModel->element_path,
|
||||||
scheduledDate: $this->date($assignmentModel->scheduled_date),
|
scheduledDate: $this->date($assignmentModel->scheduled_date),
|
||||||
position: $assignmentModel->position,
|
position: $assignmentModel->position,
|
||||||
);
|
);
|
||||||
|
|
@ -100,7 +84,7 @@ class EloquentScheduleRepository implements ScheduleRepository
|
||||||
return new Schedule(
|
return new Schedule(
|
||||||
id: $model->id,
|
id: $model->id,
|
||||||
user: $user,
|
user: $user,
|
||||||
set: $set,
|
setName: $model->set_name,
|
||||||
elementKind: $model->element_kind,
|
elementKind: $model->element_kind,
|
||||||
startDate: $this->date($model->start_date),
|
startDate: $this->date($model->start_date),
|
||||||
targetDate: $this->date($model->target_date),
|
targetDate: $this->date($model->target_date),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Schedule;
|
namespace App\Schedule;
|
||||||
|
|
||||||
use App\Set\Set;
|
|
||||||
use App\User\User;
|
use App\User\User;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
|
||||||
|
|
@ -14,7 +13,7 @@ final readonly class Schedule
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private int $id,
|
private int $id,
|
||||||
private User $user,
|
private User $user,
|
||||||
private Set $set,
|
private string $setName,
|
||||||
private string $elementKind,
|
private string $elementKind,
|
||||||
private DateTimeImmutable $startDate,
|
private DateTimeImmutable $startDate,
|
||||||
private DateTimeImmutable $targetDate,
|
private DateTimeImmutable $targetDate,
|
||||||
|
|
@ -31,9 +30,9 @@ final readonly class Schedule
|
||||||
return $this->user;
|
return $this->user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSet(): Set
|
public function getSetName(): string
|
||||||
{
|
{
|
||||||
return $this->set;
|
return $this->setName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getElementKind(): string
|
public function getElementKind(): string
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,18 @@
|
||||||
|
|
||||||
namespace App\Schedule;
|
namespace App\Schedule;
|
||||||
|
|
||||||
use App\Element\Element;
|
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
|
||||||
final readonly class ScheduleAssignment
|
final readonly class ScheduleAssignment
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param list<string> $path
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private int $id,
|
private int $id,
|
||||||
private Element $element,
|
private string $name,
|
||||||
|
private string $kind,
|
||||||
|
private array $path,
|
||||||
private DateTimeImmutable $scheduledDate,
|
private DateTimeImmutable $scheduledDate,
|
||||||
private int $position,
|
private int $position,
|
||||||
) {}
|
) {}
|
||||||
|
|
@ -19,9 +23,22 @@ final readonly class ScheduleAssignment
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getElement(): Element
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->element;
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKind(): string
|
||||||
|
{
|
||||||
|
return $this->kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public function getPath(): array
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getScheduledDate(): DateTimeImmutable
|
public function getScheduledDate(): DateTimeImmutable
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
/**
|
/**
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int $schedule_id
|
* @property int $schedule_id
|
||||||
* @property int $element_id
|
* @property string $element_name
|
||||||
|
* @property string $element_kind
|
||||||
|
* @property list<string> $element_path
|
||||||
* @property string $scheduled_date
|
* @property string $scheduled_date
|
||||||
* @property int $position
|
* @property int $position
|
||||||
*
|
*
|
||||||
|
|
@ -21,7 +23,9 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
*/
|
*/
|
||||||
#[Fillable([
|
#[Fillable([
|
||||||
'schedule_id',
|
'schedule_id',
|
||||||
'element_id',
|
'element_name',
|
||||||
|
'element_kind',
|
||||||
|
'element_path',
|
||||||
'scheduled_date',
|
'scheduled_date',
|
||||||
'position',
|
'position',
|
||||||
])]
|
])]
|
||||||
|
|
@ -38,7 +42,7 @@ class ScheduleAssignmentModel extends Model
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'schedule_id' => 'integer',
|
'schedule_id' => 'integer',
|
||||||
'element_id' => 'integer',
|
'element_path' => 'array',
|
||||||
'position' => 'integer',
|
'position' => 'integer',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
/**
|
/**
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int $user_id
|
* @property int $user_id
|
||||||
* @property int $set_id
|
* @property string $set_name
|
||||||
* @property string $element_kind
|
* @property string $element_kind
|
||||||
* @property string $start_date
|
* @property string $start_date
|
||||||
* @property string $target_date
|
* @property string $target_date
|
||||||
|
|
@ -22,7 +22,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
*/
|
*/
|
||||||
#[Fillable([
|
#[Fillable([
|
||||||
'user_id',
|
'user_id',
|
||||||
'set_id',
|
'set_name',
|
||||||
'element_kind',
|
'element_kind',
|
||||||
'start_date',
|
'start_date',
|
||||||
'target_date',
|
'target_date',
|
||||||
|
|
@ -40,7 +40,6 @@ class ScheduleModel extends Model
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'user_id' => 'integer',
|
'user_id' => 'integer',
|
||||||
'set_id' => 'integer',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class CreateSchedule
|
||||||
|
|
||||||
return $this->scheduleRepository->create(new CreateScheduleDto(
|
return $this->scheduleRepository->create(new CreateScheduleDto(
|
||||||
user: $request->user,
|
user: $request->user,
|
||||||
set: $set,
|
setName: $set->getName(),
|
||||||
elementKind: $request->elementKind,
|
elementKind: $request->elementKind,
|
||||||
startDate: $startDate,
|
startDate: $startDate,
|
||||||
targetDate: $targetDate,
|
targetDate: $targetDate,
|
||||||
|
|
@ -153,7 +153,9 @@ class CreateSchedule
|
||||||
dayCount: $dayCount,
|
dayCount: $dayCount,
|
||||||
);
|
);
|
||||||
$assignments[] = new CreateScheduleAssignmentDto(
|
$assignments[] = new CreateScheduleAssignmentDto(
|
||||||
element: $element,
|
name: $element->getName(),
|
||||||
|
kind: $element->getKind(),
|
||||||
|
path: $this->elementPath($element),
|
||||||
scheduledDate: $startDate->modify("+{$dayIndex} days"),
|
scheduledDate: $startDate->modify("+{$dayIndex} days"),
|
||||||
position: $index + 1,
|
position: $index + 1,
|
||||||
);
|
);
|
||||||
|
|
@ -162,6 +164,22 @@ class CreateSchedule
|
||||||
return $assignments;
|
return $assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
private function elementPath(Element $element): array
|
||||||
|
{
|
||||||
|
$path = [];
|
||||||
|
$currentElement = $element;
|
||||||
|
|
||||||
|
while ($currentElement !== null) {
|
||||||
|
array_unshift($path, $currentElement->getName());
|
||||||
|
$currentElement = $currentElement->getParentElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
private function dayIndex(
|
private function dayIndex(
|
||||||
int $elementIndex,
|
int $elementIndex,
|
||||||
int $elementCount,
|
int $elementCount,
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,7 @@ return new class extends Migration
|
||||||
$table->foreignId('user_id')
|
$table->foreignId('user_id')
|
||||||
->constrained('users')
|
->constrained('users')
|
||||||
->restrictOnDelete();
|
->restrictOnDelete();
|
||||||
$table->foreignId('set_id')
|
$table->string('set_name');
|
||||||
->constrained('sets')
|
|
||||||
->restrictOnDelete();
|
|
||||||
$table->string('element_kind');
|
$table->string('element_kind');
|
||||||
$table->date('start_date');
|
$table->date('start_date');
|
||||||
$table->date('target_date');
|
$table->date('target_date');
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,11 @@ return new class extends Migration
|
||||||
$table->foreignId('schedule_id')
|
$table->foreignId('schedule_id')
|
||||||
->constrained('schedules')
|
->constrained('schedules')
|
||||||
->cascadeOnDelete();
|
->cascadeOnDelete();
|
||||||
$table->foreignId('element_id')
|
$table->string('element_name');
|
||||||
->constrained('elements')
|
$table->string('element_kind');
|
||||||
->restrictOnDelete();
|
$table->json('element_path');
|
||||||
$table->date('scheduled_date');
|
$table->date('scheduled_date');
|
||||||
$table->unsignedInteger('position');
|
$table->unsignedInteger('position');
|
||||||
$table->unique(['schedule_id', 'element_id']);
|
|
||||||
$table->unique(['schedule_id', 'position']);
|
$table->unique(['schedule_id', 'position']);
|
||||||
$table->index([
|
$table->index([
|
||||||
'schedule_id',
|
'schedule_id',
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ const bibleLayout = {
|
||||||
const scheduleDetail = {
|
const scheduleDetail = {
|
||||||
schedule: {
|
schedule: {
|
||||||
id: 73,
|
id: 73,
|
||||||
set: { id: 41, name: 'Bible' },
|
set: { name: 'Bible' },
|
||||||
elementKind: 'chapter',
|
elementKind: 'chapter',
|
||||||
startDate: '2026-08-10',
|
startDate: '2026-08-10',
|
||||||
targetDate: '2026-08-12',
|
targetDate: '2026-08-12',
|
||||||
|
|
@ -55,8 +55,8 @@ const scheduleDetail = {
|
||||||
date: '2026-08-10',
|
date: '2026-08-10',
|
||||||
assignments: [
|
assignments: [
|
||||||
{
|
{
|
||||||
|
id: 1,
|
||||||
element: {
|
element: {
|
||||||
id: 4,
|
|
||||||
name: 'Chapter 1',
|
name: 'Chapter 1',
|
||||||
kind: 'chapter',
|
kind: 'chapter',
|
||||||
path: ['Genesis', 'Creation', 'Chapter 1'],
|
path: ['Genesis', 'Creation', 'Chapter 1'],
|
||||||
|
|
@ -69,8 +69,8 @@ const scheduleDetail = {
|
||||||
date: '2026-08-12',
|
date: '2026-08-12',
|
||||||
assignments: [
|
assignments: [
|
||||||
{
|
{
|
||||||
|
id: 2,
|
||||||
element: {
|
element: {
|
||||||
id: 5,
|
|
||||||
name: 'Chapter 1',
|
name: 'Chapter 1',
|
||||||
kind: 'chapter',
|
kind: 'chapter',
|
||||||
path: ['Exodus', 'Chapter 1'],
|
path: ['Exodus', 'Chapter 1'],
|
||||||
|
|
@ -213,7 +213,7 @@ describe('set scheduling', () => {
|
||||||
schedules: [
|
schedules: [
|
||||||
{
|
{
|
||||||
id: 73,
|
id: 73,
|
||||||
set: { id: 41, name: 'Bible' },
|
set: { name: 'Bible' },
|
||||||
elementKind: 'chapter',
|
elementKind: 'chapter',
|
||||||
startDate: '2026-08-10',
|
startDate: '2026-08-10',
|
||||||
targetDate: '2026-08-12',
|
targetDate: '2026-08-12',
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ const isoDateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/)
|
||||||
export const scheduleSummarySchema = z.object({
|
export const scheduleSummarySchema = z.object({
|
||||||
id: z.number().int().positive(),
|
id: z.number().int().positive(),
|
||||||
set: z.object({
|
set: z.object({
|
||||||
id: z.number().int().positive(),
|
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
}),
|
}),
|
||||||
elementKind: z.string().min(1),
|
elementKind: z.string().min(1),
|
||||||
|
|
@ -19,8 +18,8 @@ export const scheduleSummarySchema = z.object({
|
||||||
})
|
})
|
||||||
|
|
||||||
const scheduleAssignmentSchema = z.object({
|
const scheduleAssignmentSchema = z.object({
|
||||||
|
id: z.number().int().positive(),
|
||||||
element: z.object({
|
element: z.object({
|
||||||
id: z.number().int().positive(),
|
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
kind: z.string().min(1),
|
kind: z.string().min(1),
|
||||||
path: z.array(z.string().min(1)).min(1),
|
path: z.array(z.string().min(1)).min(1),
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ function pluralKind(kind: string, count: number): string {
|
||||||
<p v-if="day.assignments.length === 0" class="rest-day">Rest day</p>
|
<p v-if="day.assignments.length === 0" class="rest-day">Rest day</p>
|
||||||
|
|
||||||
<ul v-else class="assignment-list">
|
<ul v-else class="assignment-list">
|
||||||
<li v-for="assignment in day.assignments" :key="assignment.element.id">
|
<li v-for="assignment in day.assignments" :key="assignment.id">
|
||||||
<span class="assignment-path">{{ assignment.element.path.join(' / ') }}</span>
|
<span class="assignment-path">{{ assignment.element.path.join(' / ') }}</span>
|
||||||
<span class="assignment-kind">{{ humanizeKind(assignment.element.kind) }}</span>
|
<span class="assignment-kind">{{ humanizeKind(assignment.element.kind) }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue