aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json2
-rw-r--r--package.json4
-rw-r--r--src/client/documents/DocumentTypes.ts2
-rw-r--r--src/client/documents/Documents.ts12
-rw-r--r--src/client/util/CalendarManager.scss18
-rw-r--r--src/client/util/CalendarManager.tsx82
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/views/collections/CollectionCalendarView.tsx32
-rw-r--r--src/client/views/collections/CollectionView.tsx3
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx2
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx18
-rw-r--r--src/client/views/nodes/calendarBox/CalendarBox.tsx26
12 files changed, 162 insertions, 41 deletions
diff --git a/package-lock.json b/package-lock.json
index 180ff097a..2d2740381 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
+ "@internationalized/date": "^3.5.0",
"@mapbox/mapbox-gl-geocoder": "^5.0.2",
"@mui/icons-material": "^5.14.19",
"@mui/material": "^5.14.19",
@@ -37,6 +38,7 @@
"@types/dom-speech-recognition": "0.0.4",
"@types/formidable": "3.4.5",
"@types/google-maps": "^3.2.6",
+ "@types/mapbox-gl": "^2.7.19",
"@types/reveal": "^4.2.0",
"@types/supercluster": "^7.1.3",
"@types/web": "^0.0.127",
diff --git a/package.json b/package.json
index 661f8c5ec..098e30ffb 100644
--- a/package.json
+++ b/package.json
@@ -92,12 +92,12 @@
"webpack-hot-middleware": "^2.25.4"
},
"dependencies": {
+ "@adobe/react-spectrum": "^3.32.2",
"@azure/storage-blob": "^12.17.0",
"@babel/preset-env": "^7.23.5",
"@babel/preset-react": "^7.23.3",
"@bundled-es-modules/pdfjs-dist": "^3.6.172-alpha.1",
"@emotion/react": "^11.11.1",
- "@adobe/react-spectrum": "^3.32.2",
"@emotion/styled": "^11.11.0",
"@ffmpeg/core": "0.12.4",
"@ffmpeg/ffmpeg": "0.12.7",
@@ -106,6 +106,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
+ "@internationalized/date": "^3.5.0",
"@mapbox/mapbox-gl-geocoder": "^5.0.2",
"@mui/icons-material": "^5.14.19",
"@mui/material": "^5.14.19",
@@ -121,6 +122,7 @@
"@types/dom-speech-recognition": "0.0.4",
"@types/formidable": "3.4.5",
"@types/google-maps": "^3.2.6",
+ "@types/mapbox-gl": "^2.7.19",
"@types/reveal": "^4.2.0",
"@types/supercluster": "^7.1.3",
"@types/web": "^0.0.127",
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 5c2792a53..1123bcac9 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -62,5 +62,5 @@ export enum CollectionViewType {
Pile = 'pileup',
StackedTimeline = 'stacked timeline',
NoteTaking = 'notetaking',
- Calendar = 'calendar_view'
+ Calendar = 'calendar'
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index d6fd8aea3..ff14eb101 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -58,6 +58,7 @@ import { VideoBox } from '../views/nodes/VideoBox';
import { WebBox } from '../views/nodes/WebBox';
import { SearchBox } from '../views/search/SearchBox';
import { CollectionViewType, DocumentType } from './DocumentTypes';
+import { CalendarBox } from '../views/nodes/calendarBox/CalendarBox';
const {
default: { DFLT_IMAGE_NATIVE_DIM },
} = require('../views/global/globalCssVariables.module.scss');
@@ -784,6 +785,13 @@ export namespace Docs {
options: {},
},
],
+ [
+ DocumentType.CALENDAR,
+ {
+ layout: { view: CalendarBox, dataField: defaultDataKey },
+ options: {},
+ }
+ ]
]);
const suffix = 'Proto';
@@ -1146,8 +1154,8 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.MAPROUTE), new List(documents), { infoWindowOpen, ...options }, id);
}
- export function CalendarDocument(options: DocumentOptions={}, documents: Array<Doc>){
- return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), options)
+ export function CalendarDocument(options: DocumentOptions, documents: Array<Doc>){
+ return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), {...options})
}
// shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView)
diff --git a/src/client/util/CalendarManager.scss b/src/client/util/CalendarManager.scss
index 60610f298..114e19a0e 100644
--- a/src/client/util/CalendarManager.scss
+++ b/src/client/util/CalendarManager.scss
@@ -31,19 +31,20 @@
margin-top: 10px;
align-self: center;
width: 60%;
+ }
- .MuiFilledInput-input{
- padding: 10px;
- }
+ .description-container{
+ margin-top: 10px;
+ align-self: center;
+ width: 60%;
}
.date-range-picker-container{
margin-top: 5px;
- align-self:center;
-
- .react-date-range{
-
- }
+ align-self: center;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
}
.create-button-container{
@@ -57,6 +58,5 @@
border-radius: 5px;
background-color: #EFF2F7;
}
-
}
}
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 3872294db..d5d4203b1 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -10,16 +10,16 @@ import { MainViewModal } from '../views/MainViewModal';
import { TextField } from '@mui/material';
import Select from 'react-select';
import { SettingsManager } from './SettingsManager';
-import { DocCast, StrCast } from '../../fields/Types';
+import { DateCast, 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 { Button } from 'browndash-components';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Provider, useProvider, defaultTheme } from '@adobe/react-spectrum';
-
-import { DateRangePicker } from '@adobe/react-spectrum';
+import { Provider, defaultTheme } from '@adobe/react-spectrum';
+import { DateValue } from '@internationalized/date';
+import { DateRangePicker, SpectrumDateRangePickerProps } from '@adobe/react-spectrum';
import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
import { Docs } from '../documents/Documents';
import { ObservableReactComponent } from '../views/ObservableReactComponent';
@@ -33,7 +33,10 @@ interface CalendarSelectOptions {
value: string;
}
-const formatDateToString = (date: Date) => {
+const formatCalendarDateToString = (calendarDate: any) => {
+ console.log("Formatting the following date: ", calendarDate);
+ const date = new Date(calendarDate.year, calendarDate.month-1, calendarDate.day)
+ console.log(typeof date);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
@@ -121,19 +124,26 @@ export class CalendarManager extends ObservableReactComponent<{}> {
};
@action
- handleTextFieldChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+ handleCalendarTitleChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
this.calendarName = event.target.value;
};
+ @action
+ handleCalendarDescriptionChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+ this.calendarDescription = event.target.value;
+ }
+
// TODO: Make undoable
private addToCalendar = () => {
let docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar
+ console.log(targetDoc);
if (targetDoc) {
let calendar: Doc;
if (this.creationType === 'new-calendar') {
if (!this.existingCalendars.find(doc => StrCast(doc.title) === this.calendarName)) {
+ console.log('creating...')
calendar = Docs.Create.CalendarDocument(
{
title: this.calendarName,
@@ -141,6 +151,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
},
[]
);
+ console.log('successful calendar creation')
} else {
this.errorMessage = 'Calendar with this name already exists';
return;
@@ -155,15 +166,20 @@ export class CalendarManager extends ObservableReactComponent<{}> {
}
}
// Get start and end date strings
- const startDateStr = formatDateToString(this.selectedDateRange.start);
- const endDateStr = formatDateToString(this.selectedDateRange.end);
+ const startDateStr = formatCalendarDateToString(this.selectedDateRange.start);
+ const endDateStr = formatCalendarDateToString(this.selectedDateRange.end);
+
+ console.log("start date: ", startDateStr);
+ console.log("end date: ", endDateStr)
const subDocEmbedding = Doc.MakeEmbedding(targetDoc); // embedding
+ console.log("subdoc embedding", subDocEmbedding);
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
+ console.log("my calendars: ", Doc.MyCalendars);
if (this.creationType === 'new-calendar') {
Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to new calendar to dashboard calendars
}
@@ -211,6 +227,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
@action
setSelectedDateRange = (range: any) => {
+ console.log("Range: ", range);
this.selectedDateRange = range;
};
@@ -220,9 +237,12 @@ export class CalendarManager extends ObservableReactComponent<{}> {
let startDate: Date | undefined;
let endDate: Date | undefined;
try {
- startDate = this.selectedDateRange[0].startDate;
- endDate = this.selectedDateRange[0].endDate;
+ startDate = this.selectedDateRange.start;
+ endDate = this.selectedDateRange.end;
+ console.log(startDate);
+ console.log(endDate)
} catch (e: any) {
+ console.log(e);
return false; // disabled
}
if (!startDate || !endDate) return false; // disabled if any is undefined
@@ -258,8 +278,9 @@ export class CalendarManager extends ObservableReactComponent<{}> {
{this.creationType === 'new-calendar' ? (
<TextField
fullWidth
- onChange={this.handleTextFieldChange}
- placeholder="Enter calendar name..."
+ onChange={this.handleCalendarTitleChange}
+ label='Calendar name'
+ placeholder='Enter a name...'
variant="filled"
style={{
backgroundColor: 'white',
@@ -298,14 +319,41 @@ export class CalendarManager extends ObservableReactComponent<{}> {
}}></Select>
)}
</div>
+ <div className='description-container'>
+ <TextField
+ fullWidth
+ multiline
+ label='Calendar description'
+ placeholder='Enter a description (optional)...'
+ onChange={this.handleCalendarDescriptionChange}
+ variant="filled"
+ style={{
+ backgroundColor: 'white',
+ color: 'black',
+ borderRadius: '5px',
+ }}
+ />
+ </div>
<div className="date-range-picker-container">
+ <div>Select a date range: </div>
<Provider theme={defaultTheme}>
- <DateRangePicker value={this.selectedDateRange} onChange={v => this.setSelectedDateRange(v)} label="Date range" />
+ <DateRangePicker
+ aria-label='Select a date range'
+ value={this.selectedDateRange}
+ onChange={v => this.setSelectedDateRange(v)}/>
</Provider>
</div>
- <div className="create-button-container">
- <Button active={this.createButtonActive} onClick={() => {}} text="Add to Calendar" iconPlacement="right" icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
- </div>
+ {this.createButtonActive &&
+ <div className='create-button-container'>
+ <Button
+ onClick={() => this.addToCalendar()}
+ text="Add to Calendar"
+ iconPlacement="right"
+ icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
+ </div>
+
+ }
+
</div>
);
}
@@ -313,4 +361,4 @@ export class CalendarManager extends ObservableReactComponent<{}> {
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
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 61a9fa7c2..f7070a862 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1022,4 +1022,4 @@ ScriptingGlobals.add(function IsExploreMode() { return DocumentView.ExploreMode;
ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode");
ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering");
ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar");
-ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; });
+ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); \ No newline at end of file
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
new file mode 100644
index 000000000..99dc09732
--- /dev/null
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react';
+import { CollectionSubView } from "./CollectionSubView";
+import { observer } from 'mobx-react';
+import { makeObservable, observable } from 'mobx';
+import { Doc, DocListCast } from '../../../fields/Doc';
+
+@observer
+export class CollectionCalendarView extends CollectionSubView(){
+
+ constructor(props: any){
+ super(props);
+ makeObservable(this);
+ }
+
+ componentDidMount(): void {
+
+ }
+
+ componentWillUnmount(): void {
+
+ }
+
+ @observable private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars?.data);
+
+ render(){
+ return (
+ <div>
+ Hello
+ </div>
+ )
+ }
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0673b264b..0237ec95e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -28,6 +28,7 @@ import { CollectionTreeView } from './CollectionTreeView';
import './CollectionView.scss';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
import { CollectionGridView } from './collectionGrid/CollectionGridView';
+import { CollectionCalendarView} from './CollectionCalendarView';
import { CollectionLinearView } from './collectionLinear';
import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView';
@@ -122,6 +123,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
default:
case CollectionViewType.Freeform: return <CollectionFreeFormView key="collview" {...props} />;
case CollectionViewType.Schema: return <CollectionSchemaView key="collview" {...props} />;
+ case CollectionViewType.Calendar: return <CollectionCalendarView key="collview" {...props} />;
case CollectionViewType.Docking: return <CollectionDockingView key="collview" {...props} />;
case CollectionViewType.Tree: return <CollectionTreeView key="collview" {...props} />;
case CollectionViewType.Multicolumn: return <CollectionMulticolumnView key="collview" {...props} />;
@@ -146,6 +148,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
{ description: 'Schema', event: () => func(CollectionViewType.Schema), icon: 'th-list' },
{ description: 'Tree', event: () => func(CollectionViewType.Tree), icon: 'tree' },
{ description: 'Stacking', event: () => (func(CollectionViewType.Stacking)._layout_autoHeight = true), icon: 'ellipsis-v' },
+ { description: 'Calendar', event: () => func(CollectionViewType.Calendar), icon: 'columns'},
{ description: 'Notetaking', event: () => (func(CollectionViewType.NoteTaking)._layout_autoHeight = true), icon: 'ellipsis-v' },
{ description: 'Multicolumn', event: () => func(CollectionViewType.Multicolumn), icon: 'columns' },
{ description: 'Multirow', event: () => func(CollectionViewType.Multirow), icon: 'columns' },
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e161b4c4c..5b2bf4774 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -14,6 +14,7 @@ import { CollectionDockingView } from '../collections/CollectionDockingView';
import { CollectionView } from '../collections/CollectionView';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView';
+import { CollectionCalendarView } from '../collections/CollectionCalendarView';
import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox';
import { PresElementBox } from '../nodes/trails/PresElementBox';
import { SearchBox } from '../search/SearchBox';
@@ -243,6 +244,7 @@ export class DocumentContentsView extends ObservableReactComponent<
CollectionFreeFormView,
CollectionDockingView,
CollectionSchemaView,
+ CollectionCalendarView,
CollectionView,
WebBox,
KeyValueBox,
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index b627ba459..44afb8e7b 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -23,9 +23,7 @@ import { FieldView, FieldViewProps } from '../FieldView';
import { FormattedTextBox } from '../formattedText/FormattedTextBox';
import { PinProps, PresBox } from '../trails';
import { MapAnchorMenu } from './MapAnchorMenu';
-
import { ControlPosition, Layer, MapProvider, MapRef, Map as MapboxMap, Marker, MarkerProps, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl';
-import MapboxGeocoder, { GeocoderOptions } from '@mapbox/mapbox-gl-geocoder!';
import './MapBox.scss';
// import { GeocoderControl } from './GeocoderControl';
import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons';
@@ -33,7 +31,7 @@ import { Checkbox, FormControlLabel, TextField } from '@mui/material';
import * as turf from '@turf/turf';
import * as d3 from 'd3';
import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson';
-import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl!';
+import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from '!mapbox-gl';
import { CirclePicker, ColorResult } from 'react-color';
import { MarkerEvent } from 'react-map-gl/dist/esm/types';
import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons';
@@ -68,13 +66,13 @@ type PopupInfo = {
description: string;
};
-export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
- mapboxAccessToken: string;
- marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
- position: ControlPosition;
+// export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
+// mapboxAccessToken: string;
+// marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
+// position: ControlPosition;
- onResult: (...args: any[]) => void;
-};
+// onResult: (...args: any[]) => void;
+// };
type MapMarker = {
longitude: number;
@@ -1866,4 +1864,4 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
<div style={{ width: 30, height: 30 }} ref={this._dragRef} onPointerDown={this.dragToggle}>
<Button tooltip="drag to place a pushpin" icon={<FontAwesomeIcon size={'lg'} icon={'bullseye'} />} />
</div> */
-}
+} \ No newline at end of file
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
new file mode 100644
index 000000000..0aa3b4ccc
--- /dev/null
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -0,0 +1,26 @@
+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';
+
+@observer
+export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
+ public static LayoutString(fieldKey: string = 'calendar') {
+ return FieldView.LayoutString(CalendarBox, fieldKey);
+ }
+
+ constructor(props: any){
+ super(props);
+ makeObservable(this);
+ }
+
+ render(){
+ return (
+ <div></div>
+ );
+
+ }
+} \ No newline at end of file