diff options
| author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-01-25 11:35:26 -0500 |
|---|---|---|
| committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-01-25 11:35:26 -0500 |
| commit | f3dab2a56db5e4a6a3dca58185d94e1ff7d1dc32 (patch) | |
| tree | a7bc895266b53bb620dbd2dd71bad2e83b555446 /src/client/views/nodes/calendarBox | |
| parent | b5c5410b4af5d2c68d2107d3f064f6e3ec4ac3f2 (diff) | |
| parent | 136f3d9f349d54e8bdd73b6380ea47c19e5edebf (diff) | |
Merge branch 'master' into sophie-ai-images
Diffstat (limited to 'src/client/views/nodes/calendarBox')
| -rw-r--r-- | src/client/views/nodes/calendarBox/CalendarBox.tsx | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx new file mode 100644 index 000000000..748c3322e --- /dev/null +++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx @@ -0,0 +1,120 @@ +import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core'; +import dayGridPlugin from '@fullcalendar/daygrid'; +import multiMonthPlugin from '@fullcalendar/multimonth'; +import { makeObservable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { dateRangeStrToDates } from '../../../../Utils'; +import { Doc } from '../../../../fields/Doc'; +import { StrCast } from '../../../../fields/Types'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { FieldView, FieldViewProps } from '../FieldView'; + +type CalendarView = 'month' | 'multi-month' | 'week'; + +@observer +export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() { + public static LayoutString(fieldKey: string = 'calendar') { + return FieldView.LayoutString(CalendarBox, fieldKey); + } + + constructor(props: FieldViewProps) { + super(props); + makeObservable(this); + } + + componentDidMount(): void {} + + componentWillUnmount(): void {} + + _calendarRef = React.createRef<HTMLElement>(); + + 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, + }); + } + + render() { + return ( + <div className="calendar-box-conatiner"> + <div id="calendar-box-v1"></div> + </div> + ); + } +} |
