diff options
Diffstat (limited to 'src/client/util/CalendarManager.tsx')
-rw-r--r-- | src/client/util/CalendarManager.tsx | 153 |
1 files changed, 130 insertions, 23 deletions
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index 39ba41652..e471db7c6 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import './CalendarManager.scss'; import { observer } from "mobx-react"; import { action, computed, observable, runInAction } from 'mobx'; -import { Doc } from '../../fields/Doc'; +import { Doc, DocListCast } from '../../fields/Doc'; import { DocumentView } from '../views/nodes/DocumentView'; import { DictationOverlay } from '../views/DictationOverlay'; import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; @@ -10,19 +10,38 @@ import { MainViewModal } from '../views/MainViewModal'; import { TextField } from '@material-ui/core'; import Select from 'react-select'; import { SettingsManager } from './SettingsManager'; -import { StrCast } from '../../fields/Types'; +import { DocCast, StrCast } from '../../fields/Types'; import { SelectionManager } from './SelectionManager'; import { DocumentManager } from './DocumentManager'; import { DocData } from '../../fields/DocSymbols'; -import { DateRange, Range, RangeKeyDict } from 'react-date-range'; +// import { DateRange, Range, RangeKeyDict } from 'react-date-range'; import { Button } from 'browndash-components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import {DateRangePicker} from '@adobe/react-spectrum'; import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons'; -import 'react-date-range/dist/styles.css'; -import 'react-date-range/dist/theme/default.css'; +import { Docs } from '../documents/Documents'; +// import 'react-date-range/dist/styles.css'; +// import 'react-date-range/dist/theme/default.css'; type CreationType = 'new-calendar' | 'existing-calendar' | 'manage-calendars'; +interface CalendarSelectOptions { + label: string, + value: string +} + +const formatDateToString = (date: Date) => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + + return `${year}-${month}-${day}`; +} + +// TODO: If doc is already part of a calendar, display that +// TODO: For a doc already in a calendar: give option to edit date range, delete from calendar + + @observer export class CalendarManager extends React.Component<{}> { public static Instance: CalendarManager; @@ -36,11 +55,28 @@ export class CalendarManager extends React.Component<{}> { @observable private creationType: CreationType = 'new-calendar'; + @observable private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars.data); + + @computed get selectOptions() { + return this.existingCalendars.map(calendar => ({ label: StrCast(calendar.title), value: StrCast(calendar.title) })); + } + + @observable + selectedExistingCalendarOption: CalendarSelectOptions | null = null; + @observable calendarName: string = ""; + @observable + calendarDescription: string = ""; + + @observable + errorMessage: string = ""; + @action setInterationType = (type: CreationType) => { + this.errorMessage = ""; + this.calendarName = ""; this.creationType = type; } @@ -76,6 +112,60 @@ export class CalendarManager extends React.Component<{}> { } + @action + handleSelectChange = (option: any) => { + let selectOpt = option as CalendarSelectOptions; + this.selectedExistingCalendarOption = selectOpt; + this.calendarName = selectOpt.value; // or label + } + + @action + handleTextFieldChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => { + this.calendarName = event.target.value; + } + + // TODO: Make undoable + private addToCalendar = () => { + let docs = SelectionManager.Views().length < 2 ? [this.targetDoc] : SelectionManager.Views().map(docView => docView.rootDoc); + const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar + + if (targetDoc) { + let calendar: Doc; + if (this.creationType === 'new-calendar'){ + if (!this.existingCalendars.find(doc => StrCast(doc.title) === this.calendarName)){ + calendar = Docs.Create.CalendarDocument({ + title: this.calendarName, + description: this.calendarDescription + }, []); + } else { + this.errorMessage = "Calendar with this name already exists" + return; + } + } else { + // find existing calendar based on selected name (should technically always find one) + const existingCalendar = this.existingCalendars.find(calendar => StrCast(calendar.title) === this.calendarName); + if (existingCalendar) calendar = existingCalendar; + else { + this.errorMessage = "Must select an existing calendar"; + return; + } + } + // Get start and end date strings + const startDateStr = formatDateToString(this.selectedDateRange.start); + const endDateStr = formatDateToString(this.selectedDateRange.end); + + const subDocEmbedding = Doc.MakeEmbedding(targetDoc); // embedding + subDocEmbedding.embedContainer = calendar; // set embed container + subDocEmbedding.date_range = `${startDateStr}-${endDateStr}`; // set subDoc date range + + Doc.AddDocToList(calendar, 'data', subDocEmbedding); // add embedded subDoc to calendar + + Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to dashboard calendars + + } + + } + private focusOn = (contents: string) => { const title = this.targetDoc ? StrCast(this.targetDoc.title) : ''; const docs = SelectionManager.Views().length > 1 ? SelectionManager.Views().map(docView => docView.props.Document) : [this.targetDoc]; @@ -108,20 +198,19 @@ export class CalendarManager extends React.Component<{}> { }; @observable - selectedDateRange: Range[] = [{ - startDate: new Date(), - endDate: undefined, - key: 'selection' + selectedDateRange: any = [{ + start: new Date(), + end: new Date(), }] @action - setSelectedDateRange = (range: Range[]) => { + setSelectedDateRange = (range: any) => { this.selectedDateRange = range; } @computed get createButtonActive() { - if (this.calendarName.length === 0) return false // disabled if no calendar name + if (this.calendarName.length === 0 || this.errorMessage.length > 0) return false // disabled if no calendar name let startDate: Date | undefined; let endDate: Date | undefined; try { @@ -170,6 +259,7 @@ export class CalendarManager extends React.Component<{}> { {this.creationType === 'new-calendar' ? <TextField fullWidth + onChange={this.handleTextFieldChange} placeholder='Enter calendar name...' variant='filled' style={{ @@ -178,38 +268,55 @@ export class CalendarManager extends React.Component<{}> { borderRadius: '5px' }} - /> : <Select className='existing-calendar-search' placeholder='Search for existing calendar...' - isMulti + isClearable isSearchable + options={this.selectOptions} + value={this.selectedExistingCalendarOption} + onChange={this.handleSelectChange} + styles={{ + control: () => ({ + display: 'inline-flex', + width: '100%', + }), + indicatorSeparator: () => ({ + display: 'inline-flex', + visibility: 'hidden', + }), + indicatorsContainer: () => ({ + display: 'inline-flex', + textDecorationColor: 'black', + }), + valueContainer: () => ({ + display: 'inline-flex', + fontStyle: StrCast(Doc.UserDoc().userColor), + color: StrCast(Doc.UserDoc().userColor), + width: '100%', + }), + }} > - </Select> } </div> <div className='date-range-picker-container'> - <DateRange - className='react-date-range' - editableDateInputs={true} - // ranges={[selectionRange]} - onChange={item => this.setSelectedDateRange([item.selection])} - ranges={this.selectedDateRange} - // onChange={this.handleSelect} - /> + <DateRangePicker + value={this.selectedDateRange} + onChange={(v => this.setSelectedDateRange(v))} + label="Date range" /> </div> <div className='create-button-container'> <Button active={this.createButtonActive} + onClick={() => {}} text="Add to Calendar" iconPlacement='right' icon={<FontAwesomeIcon icon={faPlus as IconLookup}/>} /> </div> - </div> ) } |