Files
CT/src/View/Components/monthGrid.tsx
T

127 lines
4.6 KiB
TypeScript
Raw Normal View History

2026-09-22 21:57:22 +02:00
import * as React from "../../react";
2026-04-18 11:55:01 +00:00
import "./monthGrid.css";
import { ViewController } from "../viewController";
2024-07-26 03:14:55 +02:00
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
2026-04-18 11:55:01 +00:00
import { localeCompare } from "../../Model/Utility/utility";
import { MonthGrid } from "../../Model/Files/calendarModel";
2024-07-26 03:14:55 +02:00
2024-07-26 03:38:46 +02:00
export function MonthGrid<T>(
coreViewModel: CoreViewModel,
2026-04-01 08:29:39 +00:00
monthGrid: MonthGrid<React.MapState<T>>,
selectedDate: React.State<number>,
handleDrop: (date: string) => void,
2024-07-26 03:38:46 +02:00
) {
2026-04-01 08:29:39 +00:00
const dayLabels: HTMLElement[] = [];
let currentWeekday = monthGrid.firstDayOfWeek;
while (dayLabels.length < 7) {
dayLabels.push(
<span class="secondary">
{
coreViewModel.translations.regional.weekdays.abbreviated[
currentWeekday
]
}
2026-04-01 08:29:39 +00:00
</span>,
);
currentWeekday++;
if (currentWeekday == 7) currentWeekday = 0;
}
2024-07-26 03:29:07 +02:00
2026-04-01 08:29:39 +00:00
const offsetElements: HTMLElement[] = [];
for (let i = 0; i < monthGrid.offset; i++) {
offsetElements.push(<div></div>);
}
2024-07-26 03:14:55 +02:00
2026-04-01 08:29:39 +00:00
const converter: React.StateItemConverter<TaskViewModel> = (
taskViewModel,
) => {
const view = (
<span class="ellipsis secondary">{taskViewModel.task.name}</span>
);
2024-07-26 06:20:16 +02:00
2026-04-01 08:29:39 +00:00
taskViewModel.index.subscribe((newIndex) => {
view.style.order = newIndex;
});
2024-07-26 06:20:16 +02:00
2026-04-01 08:29:39 +00:00
return view;
};
2024-07-26 03:14:55 +02:00
2026-04-01 08:29:39 +00:00
return (
<div class="month-grid-wrapper">
<div class="day-labels">{...dayLabels}</div>
<div class="month-grid">
{...offsetElements}
{...Object.entries(monthGrid.days)
.sort((a, b) => localeCompare(a[0], b[0]))
.map((entry) => {
const [date, mapState] = entry;
2024-07-26 03:14:55 +02:00
2026-04-01 08:29:39 +00:00
const isSelected = React.createProxyState(
[selectedDate],
() => selectedDate.value == parseInt(date),
);
2024-07-26 03:38:46 +02:00
2026-04-16 11:56:42 +00:00
const isToday = React.createProxyState(
[coreViewModel.todayDate],
() => {
return (
monthGrid.isCurrentMonth == true &&
date ==
2026-04-18 11:55:01 +00:00
coreViewModel.unwrappedTodayDate
.getDate()
.toString()
2026-05-03 14:25:03 +00:00
.padStart(2, "0")
2026-04-16 11:56:42 +00:00
);
},
);
2024-07-26 05:32:07 +02:00
2026-04-01 08:29:39 +00:00
const eventCount: React.State<number> =
React.createProxyState(
[mapState],
() => mapState.value.size,
);
2024-08-27 09:58:28 -07:00
2026-04-01 08:29:39 +00:00
const hasEvents: React.State<boolean> =
React.createProxyState(
[eventCount],
() => eventCount.value != 0,
);
2024-08-27 09:58:28 -07:00
2026-04-01 08:29:39 +00:00
function select() {
selectedDate.value = parseInt(date);
}
2024-07-26 03:38:46 +02:00
2026-04-01 08:29:39 +00:00
function drop() {
handleDrop(date);
}
2024-07-26 07:07:07 +02:00
2026-04-01 08:29:39 +00:00
return (
<button
class="tile"
on:click={select}
toggle:selected={isSelected}
toggle:today={isToday}
2026-04-15 12:47:10 +00:00
on:dragover={ViewController.allowDrop}
2026-04-01 08:29:39 +00:00
on:drop={drop}
>
<div>
<b>{date}</b>
<span
class="event-count"
toggle:has-events={hasEvents}
subscribe:innerText={eventCount}
></span>
<div
class="event-list"
children:append={[mapState, converter]}
></div>
</div>
</button>
);
})}
</div>
</div>
);
2024-07-26 03:14:55 +02:00
}