aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/CalendarManager.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/CalendarManager.tsx')
-rw-r--r--src/client/util/CalendarManager.tsx229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
new file mode 100644
index 000000000..39ba41652
--- /dev/null
+++ b/src/client/util/CalendarManager.tsx
@@ -0,0 +1,229 @@
+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 { DocumentView } from '../views/nodes/DocumentView';
+import { DictationOverlay } from '../views/DictationOverlay';
+import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
+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 { SelectionManager } from './SelectionManager';
+import { DocumentManager } from './DocumentManager';
+import { DocData } from '../../fields/DocSymbols';
+import { DateRange, Range, RangeKeyDict } from 'react-date-range';
+import { Button } from 'browndash-components';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
+import 'react-date-range/dist/styles.css';
+import 'react-date-range/dist/theme/default.css';
+
+type CreationType = 'new-calendar' | 'existing-calendar' | 'manage-calendars';
+
+@observer
+export class CalendarManager extends React.Component<{}> {
+ public static Instance: CalendarManager;
+ @observable private isOpen = false;
+ @observable private targetDoc: Doc | undefined; // the target document
+ @observable private targetDocView: DocumentView | undefined; // the DocumentView of the target doc
+ @observable private dialogueBoxOpacity = 1; // for the modal
+ @observable private overlayOpacity = 0.4; // for the modal
+
+ @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
+
+ @observable private creationType: CreationType = 'new-calendar';
+
+ @observable
+ calendarName: string = "";
+
+ @action
+ setInterationType = (type: CreationType) => {
+ this.creationType = type;
+ }
+
+
+ public open = (target?: DocumentView, target_doc?: Doc) => {
+ console.log('hi');
+ runInAction(() => {
+ this.targetDoc = target_doc || target?.props.Document;
+ this.targetDocView = target;
+ DictationOverlay.Instance.hasActiveModal = true;
+ this.isOpen = this.targetDoc !== undefined;
+ })
+ };
+
+ public close = action(() => {
+ this.isOpen = false;
+ TaskCompletionBox.taskCompleted = false;
+ setTimeout(
+ action(() => {
+ DictationOverlay.Instance.hasActiveModal = false;
+ this.targetDoc = undefined;
+ }), 500
+ );
+ this.layoutDocAcls = false;
+ });
+
+ constructor(props: {}) {
+ super(props);
+ CalendarManager.Instance = this;
+ }
+
+ componentDidMount(): void {
+
+ }
+
+ 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];
+ return (
+ <span
+ className="focus-span"
+ title={title}
+ onClick={() => {
+ if (this.targetDoc && this.targetDocView && docs.length === 1) {
+ DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
+ }
+ }}
+ onPointerEnter={action(() => {
+ if (docs.length) {
+ docs.forEach(doc => doc && Doc.BrushDoc(doc));
+ this.dialogueBoxOpacity = 0.1;
+ this.overlayOpacity = 0.1;
+ }
+ })}
+ onPointerLeave={action(() => {
+ if (docs.length) {
+ docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
+ this.dialogueBoxOpacity = 1;
+ this.overlayOpacity = 0.4;
+ }
+ })}>
+ {contents}
+ </span>
+ );
+ };
+
+ @observable
+ selectedDateRange: Range[] = [{
+ startDate: new Date(),
+ endDate: undefined,
+ key: 'selection'
+ }]
+
+ @action
+ setSelectedDateRange = (range: Range[]) => {
+ this.selectedDateRange = range;
+ }
+
+ @computed
+ get createButtonActive() {
+ if (this.calendarName.length === 0) return false // disabled if no calendar name
+ let startDate: Date | undefined;
+ let endDate: Date | undefined;
+ try {
+ startDate = this.selectedDateRange[0].startDate;
+ endDate = this.selectedDateRange[0].endDate;
+ } catch (e: any){
+ return false; // disabled
+ }
+ if (!startDate || !endDate) return false; // disabled if any is undefined
+ return true;
+ }
+
+ @computed
+ get calendarInterface(){
+ let docs = SelectionManager.Views().length < 2 ? [this.targetDoc] : SelectionManager.Views().map(docView => docView.rootDoc);
+ const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData];
+
+ const currentDate = new Date();
+
+ return (
+ <div
+ className='calendar-interface'
+ style= {{
+ background: SettingsManager.userBackgroundColor,
+ color: StrCast(Doc.UserDoc().userColor)
+ }}
+ >
+ <p className="selected-doc-title" style={{ color: SettingsManager.userColor }}>
+ <b>{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}</b>
+ </p>
+ <div className='creation-type-container'>
+ <div
+ className={`calendar-creation ${this.creationType === 'new-calendar' ? 'calendar-creation-selected' : ''}`}
+ onClick={(e) => this.setInterationType('new-calendar')}
+ >
+ Add to New Calendar
+ </div>
+ <div
+ className={`calendar-creation ${this.creationType === 'existing-calendar' ? 'calendar-creation-selected' : ''}`}
+ onClick={(e) => this.setInterationType('existing-calendar')}
+ >
+ Add to Existing calendar
+ </div>
+ </div>
+ <div className='choose-calendar-container'>
+ {this.creationType === 'new-calendar' ?
+ <TextField
+ fullWidth
+ placeholder='Enter calendar name...'
+ variant='filled'
+ style={{
+ backgroundColor: 'white',
+ color: 'black',
+ borderRadius: '5px'
+
+ }}
+
+ />
+ :
+ <Select
+ className='existing-calendar-search'
+ placeholder='Search for existing calendar...'
+ isMulti
+ isSearchable
+ >
+
+ </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}
+ />
+ </div>
+ <div className='create-button-container'>
+ <Button
+ active={this.createButtonActive}
+ text="Add to Calendar"
+ iconPlacement='right'
+ icon={<FontAwesomeIcon icon={faPlus as IconLookup}/>}
+ />
+ </div>
+
+ </div>
+ )
+ }
+
+ render() {
+ return (
+ <MainViewModal
+ contents={this.calendarInterface}
+ isDisplayed={this.isOpen}
+ interactive={true}
+ dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
+ overlayDisplayedOpacity={this.overlayOpacity}
+ closeOnExternalClick={this.close}
+ />
+ )
+ }
+} \ No newline at end of file