import * as React from 'react'; import { observer } from "mobx-react"; import { Doc } from "../../../../fields/Doc"; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps, ViewBoxBaseComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from '../FieldView'; import { StrCast } from '../../../../fields/Types'; import { makeObservable } from 'mobx'; import { dateRangeStrToDates } from '../../../../Utils'; import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core' import dayGridPlugin from '@fullcalendar/daygrid' import multiMonthPlugin from '@fullcalendar/multimonth' import { faListNumeric } from '@fortawesome/free-solid-svg-icons'; type CalendarView = 'month' | 'multi-month' | 'week'; @observer export class CalendarBox extends ViewBoxBaseComponent(){ public static LayoutString(fieldKey: string = 'calendar') { return FieldView.LayoutString(CalendarBox, fieldKey); } componentDidMount(): void { } componentWillUnmount(): void { } _calendarRef = React.createRef() get dateRangeStr (){ return StrCast(this.Document.date_range); } // Choose a calendar view based on the date range get calendarViewType (): CalendarView { const [fromDate, toDate] = dateRangeStrToDates(this.dateRangeStr); if (fromDate.getFullYear() !== toDate.getFullYear() || fromDate.getMonth() !== toDate.getMonth()) return 'multi-month'; if (Math.abs(fromDate.getDay() - toDate.getDay()) > 7) return 'month'; return 'week'; } get calendarStartDate () { return this.dateRangeStr.split("|")[0]; } get calendarToDate () { return this.dateRangeStr.split("|")[1]; } get childDocs (): Doc[] { return this.childDocs; // get all sub docs for a calendar } docBackgroundColor (type: string): string { // TODO: Return a different color based on the event type return 'blue'; } get calendarEvents (): EventSourceInput | undefined { if (this.childDocs.length === 0) return undefined; return this.childDocs.map((doc, idx) => { const docTitle = StrCast(doc.title); const docDateRange = StrCast(doc.date_range); const [startDate, endDate] = dateRangeStrToDates(docDateRange); const docType = doc.type; const docDescription = doc.description ? StrCast(doc.description): ""; return { title: docTitle, start: startDate, end: endDate, allDay: false, classNames:[StrCast(docType)], // will determine the style editable: false, // subject to change in the future backgroundColor: this.docBackgroundColor(StrCast(doc.type)), color: 'white', extendedProps: { description: docDescription }, } }) } handleEventClick = (arg: EventClickArg) => { // TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc. } calendarEl: HTMLElement = document.getElementById('calendar-box-v1')!; // https://fullcalendar.io get calendar() { return new Calendar(this.calendarEl, { plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin], headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' }, initialDate: this.calendarStartDate, navLinks: true, editable: false, displayEventTime: false, displayEventEnd: false, events: this.calendarEvents, eventClick: this.handleEventClick } ) } constructor(props: any){ super(props); makeObservable(this); } render(){ return (
); } }