From d72977ad8b67f2575cad8aea988fcfa7c04f794a Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 21 Jan 2025 18:13:39 -0500 Subject: more attempts to cleanup typing, etc in chat box --- src/client/documents/DocumentTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index efe73fbbe..8aa844c0b 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -26,7 +26,7 @@ export enum DocumentType { SCRIPTING = 'script', // script editor CHAT = 'chat', // chat with GPT about files EQUATION = 'equation', // equation editor - FUNCPLOT = 'funcplot', // function plotter + FUNCPLOT = 'function plot', // function plotter MAP = 'map', DATAVIZ = 'dataviz', ANNOPALETTE = 'annopalette', -- cgit v1.2.3-70-g09d2 From 28792ad2da9f5dfab96f98f34a11136bd1453e0f Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 6 Mar 2025 10:49:20 -0500 Subject: fixed resizing height to be > 10 pixels. split pivotView out of timeView. --- src/client/documents/DocumentTypes.ts | 1 + src/client/util/CurrentUserUtils.ts | 4 +- src/client/views/DocumentDecorations.tsx | 3 +- .../views/collections/CollectionCarouselView.tsx | 2 +- .../views/collections/CollectionPivotView.tsx | 147 +++++++++++++++++++ .../views/collections/CollectionTimeView.tsx | 158 ++------------------- src/client/views/collections/CollectionView.tsx | 7 +- .../CollectionFreeFormLayoutEngines.tsx | 6 +- 8 files changed, 174 insertions(+), 154 deletions(-) create mode 100644 src/client/views/collections/CollectionPivotView.tsx (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 8aa844c0b..845aa280c 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -61,6 +61,7 @@ export enum CollectionViewType { Multirow = 'multirow', NoteTaking = 'notetaking', Pile = 'pileup', + Pivot = 'pivot', Schema = 'schema', Stacking = 'stacking', StackedTimeline = 'stacked timeline', diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 60acd5b21..8736225d0 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -826,7 +826,7 @@ pie title Minerals in my tap water return [ { btnList: new List([CollectionViewType.Freeform, CollectionViewType.Card, CollectionViewType.Carousel,CollectionViewType.Carousel3D, CollectionViewType.Masonry, CollectionViewType.Multicolumn, CollectionViewType.Multirow, CollectionViewType.Linear, - CollectionViewType.Map, CollectionViewType.NoteTaking, CollectionViewType.Schema, CollectionViewType.Stacking, + CollectionViewType.Map, CollectionViewType.NoteTaking, CollectionViewType.Pivot, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.Calendar, CollectionViewType.Grid, CollectionViewType.Tree, CollectionViewType.Time, ]), title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setView(value, shiftKey, _readOnly_); }'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}}, @@ -911,7 +911,7 @@ pie title Minerals in my tap water CurrentUserUtils.createToolButton(opts), scripts, funcs); const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet - { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, + { opts: { title: "Replicate",icon:"camera",toolTip:"Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, { opts: { title: "Recordings", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`},scripts: { script: `{ return replayWorkspace(value, _readOnly_); }`, onDragScript: `{ return startRecordingDrag(value); }`}}, { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`}, scripts: { onClick: `stopWorkspaceRecording()`}}, { opts: { title: "Play", icon: "play", toolTip: "Play recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Paused}"`}, scripts: { onClick: `resumeWorkspaceReplaying(getCurrentRecording())`}}, diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d9b6bdf1a..54e050f9f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -36,7 +36,6 @@ import { ImageBox } from './nodes/ImageBox'; import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { TagsView } from './TagsView'; -import { ImageField } from '../../fields/URLField'; interface DocumentDecorationsProps { PanelWidth: number; @@ -567,7 +566,7 @@ export class DocumentDecorations extends ObservableReactComponent {this.content} - {this.flashCardUI(this.curDoc, this.docViewProps, this.answered)} {this.navButtons} + {this.flashCardUI(this.curDoc, this.docViewProps, this.answered)} ); } diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx new file mode 100644 index 000000000..2600c0f57 --- /dev/null +++ b/src/client/views/collections/CollectionPivotView.tsx @@ -0,0 +1,147 @@ +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { returnTrue } from '../../../ClientUtils'; +import { Doc, Opt, StrListCast } from '../../../fields/Doc'; +import { List } from '../../../fields/List'; +import { ObjectField } from '../../../fields/ObjectField'; +import { ComputedField, ScriptField } from '../../../fields/ScriptField'; +import { NumCast, StrCast } from '../../../fields/Types'; +import { Docs } from '../../documents/Documents'; +import { ScriptingGlobals } from '../../util/ScriptingGlobals'; +import { FieldsDropdown } from '../FieldsDropdown'; +import { PinDocView } from '../PinFuncs'; +import { DocumentView } from '../nodes/DocumentView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; +import './CollectionTimeView.scss'; +import { ViewDefBounds, computePivotLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; +import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; + +@observer +export class CollectionPivotView extends CollectionSubView() { + _changing = false; + @observable _collapsed: boolean = false; + @observable _childClickedScript: Opt = undefined; + @observable _viewDefDivClick: Opt = undefined; + @observable _focusPivotField: Opt = undefined; + + constructor(props: SubCollectionViewProps) { + super(props); + makeObservable(this); + } + + componentDidMount() { + this._props.setContentViewBox?.(this); + runInAction(() => { + this._childClickedScript = ScriptField.MakeScript('openInLightbox(this)', { this: Doc.name }); + this._viewDefDivClick = ScriptField.MakeScript('pivotColumnClick(this,payload)', { payload: 'any' }); + }); + } + + get pivotField() { + return this._focusPivotField || StrCast(this.layoutDoc._pivotField); + } + + getAnchor = (addAsAnnotation: boolean) => { + const anchor = Docs.Create.ConfigDocument({ + title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as unknown as string, // title can take a functiono or a string + annotationOn: this.Document, + }); + PinDocView(anchor, { pinData: { collectionType: true, pivot: true, filters: true } }, this.Document); + addAsAnnotation && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_annotations', anchor); // when added as an annotation, links to anchors can be found as links to the document even if the anchors are not rendered + return anchor; + }; + + @action + scrollPreview = (docView: DocumentView, anchor: Doc /* , focusSpeed: number, options: FocusViewOptions */) => { + // if in preview, then override document's fields with view spec + this._focusFilters = StrListCast(anchor.config_docFilters); + this._focusRangeFilters = StrListCast(anchor.config_docRangeFilters); + this._focusPivotField = StrCast(anchor.config_pivotField); + return undefined; + }; + + toggleVisibility = action(() => { + this._collapsed = !this._collapsed; + }); + + goTo = (prevFilterIndex: number) => { + this.layoutDoc._pivotField = this.layoutDoc['_prevPivotFields' + prevFilterIndex]; + this.layoutDoc._childFilters = ObjectField.MakeCopy(this.layoutDoc['_prevDocFilter' + prevFilterIndex] as ObjectField); + this.layoutDoc._childFiltersByRanges = ObjectField.MakeCopy(this.layoutDoc['_prevDocRangeFilters' + prevFilterIndex] as ObjectField); + this.layoutDoc._prevFilterIndex = prevFilterIndex; + }; + + @action + contentsDown = () => { + const prevFilterIndex = NumCast(this.layoutDoc._prevFilterIndex); + if (prevFilterIndex > 0) { + this.goTo(prevFilterIndex - 1); + } else { + this.layoutDoc._childFilters = new List([]); + } + }; + layoutEngine = () => computePivotLayout.name; + @computed get contents() { + return ( +
+ +
+ ); + } + + render() { + return ( +
+ {this.contents} +
+ { + this.layoutDoc._pivotField = fieldKey; + }} + placeholder={StrCast(this.layoutDoc._pivotField)} + /> +
+
+ ); + } +} + +// eslint-disable-next-line prefer-arrow-callback +ScriptingGlobals.add(function pivotColumnClick(pivotDoc: Doc, bounds: ViewDefBounds) { + const pivotField = StrCast(pivotDoc._pivotField, 'author'); + let prevFilterIndex = NumCast(pivotDoc._prevFilterIndex); + const originalFilter = StrListCast(ObjectField.MakeCopy(pivotDoc._childFilters as ObjectField)); + pivotDoc['_prevDocFilter' + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._childFilters as ObjectField); + pivotDoc['_prevDocRangeFilters' + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._childFiltersByRanges as ObjectField); + pivotDoc['_prevPivotFields' + prevFilterIndex] = pivotField; + pivotDoc._prevFilterIndex = ++prevFilterIndex; + pivotDoc._childFilters = new List(); + setTimeout( + action(() => { + const filterVals = bounds.payload as string[]; + filterVals.map(filterVal => Doc.setDocFilter(pivotDoc, pivotField, filterVal, 'check')); + const pivotView = DocumentView.getDocumentView(pivotDoc); + if (pivotDoc && pivotView?.ComponentView instanceof CollectionPivotView && filterVals.length === 1) { + if (pivotView?.ComponentView.childDocs.length && pivotView.ComponentView.childDocs[0][filterVals[0]]) { + pivotDoc._pivotField = filterVals[0]; + } + } + const newFilters = StrListCast(pivotDoc._childFilters); + if (newFilters.length && originalFilter.length && newFilters.lastElement() === originalFilter.lastElement()) { + pivotDoc._prevFilterIndex = --prevFilterIndex; + pivotDoc['_prevDocFilter' + prevFilterIndex] = undefined; + pivotDoc['_prevDocRangeFilters' + prevFilterIndex] = undefined; + pivotDoc['_prevPivotFields' + prevFilterIndex] = undefined; + } + }) + ); +}); diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index d75c633ac..98bd06221 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -1,33 +1,22 @@ -import { action, computed, makeObservable, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; import { Doc, Opt, StrListCast } from '../../../fields/Doc'; -import { List } from '../../../fields/List'; -import { ObjectField } from '../../../fields/ObjectField'; -import { listSpec } from '../../../fields/Schema'; -import { ComputedField, ScriptField } from '../../../fields/ScriptField'; -import { Cast, NumCast, StrCast } from '../../../fields/Types'; +import { NumCast, StrCast } from '../../../fields/Types'; import { Docs } from '../../documents/Documents'; -import { ScriptingGlobals } from '../../util/ScriptingGlobals'; -import { ContextMenu } from '../ContextMenu'; -import { ContextMenuProps } from '../ContextMenuItem'; import { FieldsDropdown } from '../FieldsDropdown'; import { PinDocView } from '../PinFuncs'; import { DocumentView } from '../nodes/DocumentView'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import './CollectionTimeView.scss'; -import { ViewDefBounds, computePivotLayout, computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; +import { computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; @observer export class CollectionTimeView extends CollectionSubView() { - _changing = false; - @observable _layoutEngine = computePivotLayout.name; @observable _collapsed: boolean = false; - @observable _childClickedScript: Opt = undefined; - @observable _viewDefDivClick: Opt = undefined; @observable _focusPivotField: Opt = undefined; constructor(props: SubCollectionViewProps) { @@ -37,10 +26,6 @@ export class CollectionTimeView extends CollectionSubView() { componentDidMount() { this._props.setContentViewBox?.(this); - runInAction(() => { - this._childClickedScript = ScriptField.MakeScript('openInLightbox(this)', { this: Doc.name }); - this._viewDefDivClick = ScriptField.MakeScript('pivotColumnClick(this,payload)', { payload: 'any' }); - }); } get pivotField() { @@ -49,19 +34,10 @@ export class CollectionTimeView extends CollectionSubView() { getAnchor = (addAsAnnotation: boolean) => { const anchor = Docs.Create.ConfigDocument({ - title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as unknown as string, // title can take a functiono or a string annotationOn: this.Document, }); PinDocView(anchor, { pinData: { collectionType: true, pivot: true, filters: true } }, this.Document); - - if (addAsAnnotation) { - // when added as an annotation, links to anchors can be found as links to the document even if the anchors are not rendered - if (Cast(this.dataDoc[this._props.fieldKey + '_annotations'], listSpec(Doc), null) !== undefined) { - Cast(this.dataDoc[this._props.fieldKey + '_annotations'], listSpec(Doc), []).push(anchor); - } else { - this.dataDoc[this._props.fieldKey + '_annotations'] = new List([anchor]); - } - } + addAsAnnotation && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_annotations', anchor); // when added as an annotation, links to anchors can be found as links to the document even if the anchors are not rendered return anchor; }; @@ -74,7 +50,6 @@ export class CollectionTimeView extends CollectionSubView() { return undefined; }; - layoutEngine = () => this._layoutEngine; toggleVisibility = action(() => { this._collapsed = !this._collapsed; }); @@ -126,105 +101,24 @@ export class CollectionTimeView extends CollectionSubView() { ); }; - goTo = (prevFilterIndex: number) => { - this.layoutDoc._pivotField = this.layoutDoc['_prevPivotFields' + prevFilterIndex]; - this.layoutDoc._childFilters = ObjectField.MakeCopy(this.layoutDoc['_prevDocFilter' + prevFilterIndex] as ObjectField); - this.layoutDoc._childFiltersByRanges = ObjectField.MakeCopy(this.layoutDoc['_prevDocRangeFilters' + prevFilterIndex] as ObjectField); - this.layoutDoc._prevFilterIndex = prevFilterIndex; - }; - - @action - contentsDown = () => { - const prevFilterIndex = NumCast(this.layoutDoc._prevFilterIndex); - if (prevFilterIndex > 0) { - this.goTo(prevFilterIndex - 1); - } else { - this.layoutDoc._childFilters = new List([]); - } - }; - + layoutEngine = () => computeTimelineLayout.name; @computed get contents() { return ( -
+
); } - public static SyncTimelineToPresentation(doc: Doc) { - const fieldKey = Doc.LayoutFieldKey(doc); - doc[fieldKey + '-timelineCur'] = ComputedField.MakeFunction("(activePresentationItem()[this._pivotField || 'year'] || 0)"); - } - specificMenu = () => { - const layoutItems: ContextMenuProps[] = []; - const doc = this.layoutDoc; - - layoutItems.push({ - description: 'Force Timeline', - event: () => { - doc._forceRenderEngine = computeTimelineLayout.name; - }, - icon: 'compress-arrows-alt', - }); - layoutItems.push({ - description: 'Force Pivot', - event: () => { - doc._forceRenderEngine = computePivotLayout.name; - }, - icon: 'compress-arrows-alt', - }); - layoutItems.push({ - description: 'Auto Time/Pivot layout', - event: () => { - doc._forceRenderEngine = undefined; - }, - icon: 'compress-arrows-alt', - }); - layoutItems.push({ description: 'Sync with presentation', event: () => CollectionTimeView.SyncTimelineToPresentation(doc), icon: 'compress-arrows-alt' }); - - ContextMenu.Instance.addItem({ description: 'Options...', subitems: layoutItems, icon: 'eye' }); - }; - render() { - let nonNumbers = 0; - this.childDocs.forEach(doc => { - const num = NumCast(doc[this.pivotField], Number(StrCast(doc[this.pivotField]))); - if (isNaN(num)) { - nonNumbers++; - } - }); - const forceLayout = StrCast(this.layoutDoc._forceRenderEngine); - const doTimeline = forceLayout ? forceLayout === computeTimelineLayout.name : nonNumbers / this.childDocs.length < 0.1 && this._props.PanelWidth() / this._props.PanelHeight() > 6; - if (doTimeline !== (this._layoutEngine === computeTimelineLayout.name)) { - if (!this._changing) { - this._changing = true; - setTimeout( - action(() => { - this._layoutEngine = doTimeline ? computeTimelineLayout.name : computePivotLayout.name; - this._changing = false; - }), - 0 - ); - } - } - return ( -
+
{this.contents} - {!this._props.isSelected() || !doTimeline ? null : ( - <> -
-
-
- - )}
+ {!this._props.isSelected() ? null : ( + <> +
+
+
+ + )}
); } } - -// eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function pivotColumnClick(pivotDoc: Doc, bounds: ViewDefBounds) { - const pivotField = StrCast(pivotDoc._pivotField, 'author'); - let prevFilterIndex = NumCast(pivotDoc._prevFilterIndex); - const originalFilter = StrListCast(ObjectField.MakeCopy(pivotDoc._childFilters as ObjectField)); - pivotDoc['_prevDocFilter' + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._childFilters as ObjectField); - pivotDoc['_prevDocRangeFilters' + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._childFiltersByRanges as ObjectField); - pivotDoc['_prevPivotFields' + prevFilterIndex] = pivotField; - pivotDoc._prevFilterIndex = ++prevFilterIndex; - pivotDoc._childFilters = new List(); - setTimeout( - action(() => { - const filterVals = bounds.payload as string[]; - filterVals.map(filterVal => Doc.setDocFilter(pivotDoc, pivotField, filterVal, 'check')); - const pivotView = DocumentView.getDocumentView(pivotDoc); - if (pivotDoc && pivotView?.ComponentView instanceof CollectionTimeView && filterVals.length === 1) { - if (pivotView?.ComponentView.childDocs.length && pivotView.ComponentView.childDocs[0][filterVals[0]]) { - pivotDoc._pivotField = filterVals[0]; - } - } - const newFilters = StrListCast(pivotDoc._childFilters); - if (newFilters.length && originalFilter.length && newFilters.lastElement() === originalFilter.lastElement()) { - pivotDoc._prevFilterIndex = --prevFilterIndex; - pivotDoc['_prevDocFilter' + prevFilterIndex] = undefined; - pivotDoc['_prevDocRangeFilters' + prevFilterIndex] = undefined; - pivotDoc['_prevPivotFields' + prevFilterIndex] = undefined; - } - }) - ); -}); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index a4900e9d7..7ba8989ce 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -15,12 +15,14 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { FieldView } from '../nodes/FieldView'; import { OpenWhere } from '../nodes/OpenWhere'; +import { CalendarBox } from '../nodes/calendarBox/CalendarBox'; import { CollectionCardView } from './CollectionCardDeckView'; import { CollectionCarousel3DView } from './CollectionCarousel3DView'; import { CollectionCarouselView } from './CollectionCarouselView'; import { CollectionDockingView } from './CollectionDockingView'; import { CollectionNoteTakingView } from './CollectionNoteTakingView'; import { CollectionPileView } from './CollectionPileView'; +import { CollectionPivotView } from './CollectionPivotView'; import { CollectionStackingView } from './CollectionStackingView'; import { CollectionViewProps, SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; @@ -32,7 +34,6 @@ import { CollectionLinearView } from './collectionLinear'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; -import { CalendarBox } from '../nodes/calendarBox/CalendarBox'; @observer export class CollectionView extends ViewBoxAnnotatableComponent() { @@ -105,6 +106,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent; case CollectionViewType.Masonry: return ; case CollectionViewType.Time: return ; + case CollectionViewType.Pivot: return ; case CollectionViewType.Grid: return ; case CollectionViewType.Card: return ; } @@ -126,7 +128,8 @@ export class CollectionView extends ViewBoxAnnotatableComponent func(CollectionViewType.Carousel), icon: 'columns' }, { description: '3D Carousel', event: () => func(CollectionViewType.Carousel3D), icon: 'columns' }, { description: 'Calendar', event: () => func(CollectionViewType.Calendar), icon: 'columns' }, - { description: 'Pivot/Time', event: () => func(CollectionViewType.Time), icon: 'columns' }, + { description: 'Pivot', event: () => func(CollectionViewType.Pivot), icon: 'columns' }, + { description: 'Time', event: () => func(CollectionViewType.Time), icon: 'columns' }, { description: 'Map', event: () => func(CollectionViewType.Map), icon: 'globe-americas' }, { description: 'Grid', event: () => func(CollectionViewType.Grid), icon: 'th-list' }, ]; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index bebdbd731..241a56a88 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -4,7 +4,7 @@ import { Id, ToString } from '../../../../fields/FieldSymbols'; import { ObjectField } from '../../../../fields/ObjectField'; import { RefField } from '../../../../fields/RefField'; import { listSpec } from '../../../../fields/Schema'; -import { Cast, NumCast, StrCast } from '../../../../fields/Types'; +import { Cast, DateCast, NumCast, StrCast } from '../../../../fields/Types'; import { aggregateBounds } from '../../../../Utils'; export interface ViewDefBounds { @@ -107,7 +107,7 @@ export function computePassLayout(poolData: Map, pivotDoc: Doc } function toNumber(val: FieldResult) { - return val === undefined ? undefined : NumCast(val, Number(StrCast(val))); + return val === undefined ? undefined : DateCast(val) ? DateCast(val).date.getMilliseconds() : NumCast(val, Number(StrCast(val))); } export function computeStarburstLayout(poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps: any */) { @@ -295,7 +295,7 @@ export function computeTimelineLayout(poolData: Map, pivotDoc: let minTime = minTimeReq === undefined ? Number.MAX_VALUE : minTimeReq; let maxTime = maxTimeReq === undefined ? -Number.MAX_VALUE : maxTimeReq; childPairs.forEach(pair => { - const num = NumCast(pair.layout[timelineFieldKey], Number(StrCast(pair.layout[timelineFieldKey]))); + const num = toNumber(pair.layout[timelineFieldKey]) ?? 0; if (!isNaN(num) && (!minTimeReq || num >= minTimeReq) && (!maxTimeReq || num <= maxTimeReq)) { !pivotDateGroups.get(num) && pivotDateGroups.set(num, []); pivotDateGroups.get(num)!.push(pair.layout); -- cgit v1.2.3-70-g09d2 From 980d7d9f747b1ee0ca0ad86df18f98684de5b193 Mon Sep 17 00:00:00 2001 From: aaravkumar Date: Thu, 6 Mar 2025 13:42:53 -0500 Subject: daily journal node --- package-lock.json | 19 +++- src/client/documents/DocUtils.ts | 13 +++ src/client/documents/DocumentTypes.ts | 2 + src/client/documents/Documents.ts | 52 ++++++++++ src/client/views/Main.tsx | 4 +- .../views/nodes/formattedText/DailyJournal.tsx | 108 +++++++++++++++++++++ src/server/ApiManagers/AssistantManager.ts | 3 +- 7 files changed, 195 insertions(+), 6 deletions(-) create mode 100644 src/client/views/nodes/formattedText/DailyJournal.tsx (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/package-lock.json b/package-lock.json index 3bbc68a99..e7e666911 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31233,6 +31233,15 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, + "node_modules/openai/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/opentype.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz", @@ -39095,12 +39104,14 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.1.0.tgz", + "integrity": "sha512-A7Jxrg7+eV+eZR/CIdESDnRGFb6/bcKukGvJBB5snI6cw3is1c2qamkYstC1bY1p08TyMRlN9eTMkxmnKJBPBw==", "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">= 14" + "node": ">= 8" } }, "node_modules/webidl-conversions": { diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 23032b62e..5a39a9720 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -396,6 +396,19 @@ export namespace DocUtils { event: e => (DocumentView.Selected().lastElement().ComponentView as CollectionFreeFormView)?.showSmartDraw(e?.x || 0, e?.y || 0), icon: 'file', }); + + // AARAV ADD // + documentList.push({ + description: ':Daily Journal', + event: undoable(() => { + const newDoc = Docs.Create.DailyJournalDocument('', { x, y }); + docAdder?.(newDoc); + }, 'Create Daily Journal'), + icon: 'book', + }); + + // AARAV ADD // + ContextMenu.Instance.addItem({ description: 'Create document', subitems: documentList, diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 8aa844c0b..65cd499c9 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -44,6 +44,8 @@ export enum DocumentType { SCRIPTDB = 'scriptdb', // database of scripts GROUPDB = 'groupdb', // database of groups + + JOURNAL = 'journal', // AARAV ADD } export enum CollectionViewType { Invalid = 'invalid', diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 891223952..ce8c8a6b7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -19,6 +19,7 @@ import { DocServer } from '../DocServer'; import { dropActionType } from '../util/DropActionTypes'; import { CollectionViewType, DocumentType } from './DocumentTypes'; import { Id } from '../../fields/FieldSymbols'; +import { DailyJournal } from '../views/nodes/formattedText/DailyJournal'; class EmptyBox { public static LayoutString() { @@ -569,6 +570,19 @@ export namespace Docs { options: { acl: '' }, }, ], + + // AARAV ADD // + [ + DocumentType.JOURNAL, + { + layout: { view: EmptyBox, dataField: 'text' }, + options: { + title: 'Daily Journal', + acl_Guest: SharingPermissions.View, + }, + }, + ], + // AARAV ADD // ]); const suffix = 'Proto'; @@ -651,6 +665,7 @@ export namespace Docs { return undefined; } const { layout } = template; + // create title const upper = suffix.toUpperCase(); const title = prototypeId.toUpperCase().replace(upper, `_${upper}`); @@ -899,6 +914,43 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey); } + // AARAV ADD // + + export function DailyJournalDocument(text: string | RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') { + const rtf = { + doc: { + type: 'doc', + content: [ + { + type: 'paragraph', + content: [ + { + type: 'text', + text, + }, + ], + }, + ], + }, + selection: { type: 'text', anchor: 1, head: 1 }, + storedMarks: [], + Text: text, + }; + const field = text instanceof RichTextField ? text : text ? new RichTextField(JSON.stringify(rtf), text) : options.text instanceof RichTextField ? options.text : undefined; + + return InstanceFromProto(Prototypes.get(DocumentType.JOURNAL), field, { + title: new Date().toLocaleDateString(undefined, { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + }), + ...options, + }); + } + + // AARAV ADD // + export function LinkDocument(source: Doc, target: Doc, options: DocumentOptions = {}, id?: string) { const linkDoc = InstanceFromProto( Prototypes.get(DocumentType.LINK), diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index dda543470..8087a0e6d 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -29,7 +29,6 @@ import { CollectionSchemaView } from './collections/collectionSchema/CollectionS import { SchemaRowBox } from './collections/collectionSchema/SchemaRowBox'; import './global/globalScripts'; import { AudioBox } from './nodes/AudioBox'; -import { ChatBox } from './nodes/chatbot/chatboxcomponents/ChatBox'; import { ComparisonBox } from './nodes/ComparisonBox'; import { DataVizBox } from './nodes/DataVizBox/DataVizBox'; import { DiagramBox } from './nodes/DiagramBox'; @@ -53,6 +52,8 @@ import { ScriptingBox } from './nodes/ScriptingBox'; import { VideoBox } from './nodes/VideoBox'; import { WebBox } from './nodes/WebBox'; import { CalendarBox } from './nodes/calendarBox/CalendarBox'; +import { ChatBox } from './nodes/chatbot/chatboxcomponents/ChatBox'; +import { DailyJournal } from './nodes/formattedText/DailyJournal'; import { DashDocCommentView } from './nodes/formattedText/DashDocCommentView'; import { DashDocView } from './nodes/formattedText/DashDocView'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; @@ -119,6 +120,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; DocumentContentsView.Init(KeyValueBox.LayoutString(), { StickerPalette: StickerPalette, FormattedTextBox, + DailyJournal, // AARAV ImageBox, FontIconBox, LabelBox, diff --git a/src/client/views/nodes/formattedText/DailyJournal.tsx b/src/client/views/nodes/formattedText/DailyJournal.tsx new file mode 100644 index 000000000..9decbfaf0 --- /dev/null +++ b/src/client/views/nodes/formattedText/DailyJournal.tsx @@ -0,0 +1,108 @@ +import { action, makeObservable, observable } from 'mobx'; +import * as React from 'react'; +import { RichTextField } from '../../../../fields/RichTextField'; +import { Docs } from '../../../documents/Documents'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { ViewBoxAnnotatableComponent } from '../../DocComponent'; +import { FieldView, FieldViewProps } from '../FieldView'; +import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox'; + +export class DailyJournal extends ViewBoxAnnotatableComponent() { + @observable journalDate: string; + + public static LayoutString(fieldStr: string) { + return FieldView.LayoutString(DailyJournal, fieldStr); + } + + constructor(props: FormattedTextBoxProps) { + super(props); + makeObservable(this); + this.journalDate = this.getFormattedDate(); + + console.log('Constructor: Setting initial title and text...'); + this.setDailyTitle(); + this.setDailyText(); + } + + getFormattedDate(): string { + const date = new Date().toLocaleDateString(undefined, { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + }); + console.log('📆 getFormattedDate():', date); + return date; + } + + @action + setDailyTitle() { + console.log('setDailyTitle() called...'); + console.log('Current title before update:', this.dataDoc.title); + + if (!this.dataDoc.title || this.dataDoc.title !== this.journalDate) { + console.log('Updating title to:', this.journalDate); + this.dataDoc.title = this.journalDate; + } + + console.log('New title after update:', this.dataDoc.title); + } + + @action + setDailyText() { + console.log('setDailyText() called...'); + const initialText = `Journal Entry - ${this.journalDate}\n\nStart writing here...`; + + console.log('Checking if dataDoc has text field...'); + + console.log('Setting new text field with:', initialText); + this.dataDoc[this.fieldKey] = new RichTextField( + JSON.stringify({ + doc: { + type: 'doc', + content: [{ type: 'paragraph', content: [{ type: 'text', text: initialText }] }], + }, + selection: { type: 'text', anchor: 1, head: 1 }, + storedMarks: [], + }), + initialText + ); + + console.log('Current text field:', this.dataDoc[this.fieldKey]); + } + + componentDidMount(): void { + console.log('componentDidMount() triggered...'); + this.setDailyTitle(); + this.setDailyText(); + } + + componentDidUpdate(prevProps: Readonly): void { + console.log('componentDidUpdate() triggered...'); + super.componentDidUpdate(prevProps); + this.setDailyTitle(); + this.setDailyText(); + } + + render() { + return
+ + +
; + } +} + +Docs.Prototypes.TemplateMap.set(DocumentType.JOURNAL, { + layout: { view: DailyJournal, dataField: 'text' }, + options: { + acl: '', + _height: 35, + _xMargin: 10, + _yMargin: 10, + _layout_nativeDimEditable: true, + _layout_reflowVertical: true, + _layout_reflowHorizontal: true, + defaultDoubleClick: 'ignore', + systemIcon: 'BsFileEarmarkTextFill', + }, +}); diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts index c41f697db..e859e5c5f 100644 --- a/src/server/ApiManagers/AssistantManager.ts +++ b/src/server/ApiManagers/AssistantManager.ts @@ -25,6 +25,7 @@ import { DashUploadUtils } from '../DashUploadUtils'; import { Method } from '../RouteManager'; import { filesDirectory, publicDirectory } from '../SocketData'; import ApiManager, { Registration } from './ApiManager'; +import { env } from 'process'; // Enumeration of directories where different file types are stored export enum Directory { @@ -89,7 +90,7 @@ export default class AssistantManager extends ApiManager { protected initialize(register: Registration): void { // Initialize Google Custom Search API const customsearch = google.customsearch('v1'); - const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); + const openai = new OpenAI({ apiKey: env.OPENAI_API_KEY }); // Register Wikipedia summary API route register({ -- cgit v1.2.3-70-g09d2 From df173b02ffb7e2937d20a02beec1815b3af7c34e Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Mar 2025 17:40:08 -0400 Subject: removed simulation doc. fixed empty imageBox uploading. fixed script typechecking. fixed metadata doc. fixed setting background colors of docs that have a template. --- src/client/documents/DocUtils.ts | 7 +++++-- src/client/documents/DocumentTypes.ts | 1 - src/client/documents/Documents.ts | 4 ---- src/client/util/CurrentUserUtils.ts | 16 ++++++++-------- src/client/util/Scripting.ts | 7 +++---- src/client/views/Main.tsx | 2 -- src/client/views/StyleProvider.tsx | 2 +- .../collections/collectionSchema/SchemaCellField.tsx | 2 -- src/client/views/nodes/DiagramBox.tsx | 5 ++++- src/client/views/nodes/DocumentContentsView.tsx | 11 ++++------- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 18 +++++++----------- src/fields/Doc.ts | 1 - 13 files changed, 33 insertions(+), 45 deletions(-) (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index b216551d5..1c7ccadd1 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -691,6 +691,7 @@ export namespace DocUtils { } generatedDocuments.push(doc); } + return doc; } export function GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, annotationOn?: Doc, backgroundColor?: string) { @@ -841,7 +842,7 @@ export namespace DocUtils { export function uploadFileToDoc(file: File, options: DocumentOptions, overwriteDoc: Doc) { const generatedDocuments: Doc[] = []; // Since this file has an overwriteDoc, we can set the client tracking guid to the overwriteDoc's guid. - Networking.UploadFilesToServer([{ file, guid: overwriteDoc[Id] }]).then(upfiles => { + return Networking.UploadFilesToServer([{ file, guid: overwriteDoc[Id] }]).then(upfiles => { const { source: { newFilename, mimetype }, result, @@ -851,7 +852,9 @@ export namespace DocUtils { overwriteDoc.loadingError = result.message; Doc.removeCurrentlyLoading(overwriteDoc); } - } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc); + return undefined; + } + return newFilename && mimetype ? processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc) : undefined; }); } diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 00f5dedd6..03626107f 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -31,7 +31,6 @@ export enum DocumentType { DATAVIZ = 'dataviz', ANNOPALETTE = 'annopalette', LOADING = 'loading', - SIMULATION = 'simulation', // physics simulation MESSAGE = 'message', // chat message // special purpose wrappers that either take no data or are compositions of lower level types diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4b5979965..317bb7feb 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1150,9 +1150,5 @@ export namespace Docs { export function DelegateDocument(proto: Doc, options: DocumentOptions = {}) { return InstanceFromProto(proto, undefined, options); } - - export function SimulationDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.SIMULATION), undefined, { ...(options || {}) }); - } } } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 778b522c4..21e1d3e12 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -109,7 +109,7 @@ export class CurrentUserUtils { const reqdClickList = reqdTempOpts.map(opts => { const allOpts = {...reqdClickOpts, ...opts.opts}; const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(fdoc => fdoc.title === opts.opts.title): undefined; - return DocUtils.AssignOpts(clickDoc, allOpts) ?? Docs.Create.ScriptingDocument(ScriptField.MakeScript(opts.script, allOpts),allOpts); + return DocUtils.AssignOpts(clickDoc, allOpts) ?? Docs.Create.ScriptingDocument(ScriptField.MakeScript(opts.script),allOpts); }); const reqdOpts:DocumentOptions = { title: "child click editors", _height:75, isSystem: true}; @@ -270,21 +270,23 @@ export class CurrentUserUtils { // "
" + // " " + - // " " + + // " " + // "
"; const headerBtnHgt = 10; const headerTemplate = (opts:DocumentOptions) => MakeTemplate(Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { ...opts, title: "Header Template", - layout:` + layout:` - Metadata + Metadata + ` }, "header")); const slideView = (opts:DocumentOptions) => MakeTemplate(Docs.Create.MultirowDocument( [ - Docs.Create.MulticolumnDocument([], { title: "hero", _height: 200, isSystem: true }), + Docs.Create.MulticolumnDocument([], { title: "hero", _xMargin: 10, _height: 200, isSystem: true }), Docs.Create.TextDocument("", { title: "text", _layout_fitWidth:true, _height: 100, isSystem: true, text_fontFamily: StrCast(Doc.UserDoc().fontFamily), text_fontSize: StrCast(Doc.UserDoc().fontSize) }) ], {...opts, title: "Slide View Template"})); const plotlyApi = () => { @@ -390,7 +392,6 @@ pie title Minerals in my tap water {key: "Image", creator: opts => Docs.Create.ImageDocument("", opts), opts: { _width: 400, _height:400 }}, {key: "Equation", creator: opts => Docs.Create.EquationDocument("",opts), opts: { _width: 50, _height: 50, nativeWidth: 40, nativeHeight: 40, _xMargin: 10, _yMargin: 10}}, {key: "Noteboard", creator: opts => Docs.Create.NoteTakingDocument([], opts), opts: { _width: 250, _height: 200, _layout_fitWidth: true}}, - {key: "Simulation", creator: opts => Docs.Create.SimulationDocument(opts), opts: { _width: 300, _height: 300, }}, {key: "Collection", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 150, _height: 100, _layout_fitWidth: true }}, {key: "Webpage", creator: opts => Docs.Create.WebDocument("",opts), opts: { _width: 400, _height: 512, _nativeWidth: 850, data_useCors: true, }}, {key: "Comparison", creator: opts => Docs.Create.ComparisonDocument("", opts), opts: { _width: 300, _height: 300 }}, @@ -428,7 +429,6 @@ pie title Minerals in my tap water { toolTip: "Tap or drag to create an equation", title: "Math", icon: "calculator", dragFactory: doc.emptyEquation as Doc, clickFactory: DocCast(doc.emptyEquation)}, { toolTip: "Tap or drag to create a mermaid node", title: "Mermaids", icon: "rocket", dragFactory: doc.emptyMermaids as Doc, clickFactory: DocCast(doc.emptyMermaids)}, { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)}, - { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "book", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)}, { toolTip: "Tap or drag to create an image", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)}, { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)}, @@ -443,7 +443,7 @@ pie title Minerals in my tap water { toolTip: "Tap or drag to create a button", title: "Button", icon: "circle", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)}, { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)}, - { toolTip: "Tap or drag to create a journal entry", title: "Journal", icon: "note", dragFactory: doc.emptyDailyJournal as Doc,clickFactory:DocCast(doc.emptyDataJournal), }, + { toolTip: "Tap or drag to create a journal entry", title: "Journal", icon: "book", dragFactory: doc.emptyDailyJournal as Doc,clickFactory:DocCast(doc.emptyDataJournal), }, { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "person-chalkboard", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a view slide", title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc, clickFactory: DocCast(doc.emptyViewSlide), openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize", dragFactory: doc.emptyHeader as Doc, clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} }, diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index c6d98496a..b0886a67c 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -54,6 +54,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: ts (diag.code !== 2552 ||!Object.keys(scriptingGlobals).includes(diagnostics[0].messageText.toString().match(/Cannot find name '([A-Za-z0-9$-_]+)'/)?.[1]??"-------")) ); // prettier-ignore if ((options.typecheck !== false && errors.length) || !script) { + console.log('Script Compile Failed: ' + script + ' ', errors); return { compiled: false, errors }; } @@ -228,10 +229,8 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp } paramNames.push(...Object.keys(params).filter(p => p !== 'this' && !Object.keys(capturedVariables).includes(p))); - const paramList = paramNames.map(key => { - const val = typeof params[key] === 'string' && params[key].length && !'"\'`'.includes(params[key][0]) ? `"${params[key]}"` : params[key]; - return `${key}: ${val}`; - }); + const paramList = paramNames.map(key => `${key}: ${params[key] === Doc.name ? 'any' : params[key]}`); + for (const key in capturedVariables) { if (key !== 'this') { const val = capturedVariables[key]; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index e5347e692..22725a2b9 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -45,7 +45,6 @@ import { LoadingBox } from './nodes/LoadingBox'; import { MapBox } from './nodes/MapBox/MapBox'; import { MapPushpinBox } from './nodes/MapBox/MapPushpinBox'; import { PDFBox } from './nodes/PDFBox'; -import { PhysicsSimulationBox } from './nodes/PhysicsBox/PhysicsSimulationBox'; import { RecordingBox } from './nodes/RecordingBox'; import { ScreenshotBox } from './nodes/ScreenshotBox'; import { ScriptingBox } from './nodes/ScriptingBox'; @@ -154,7 +153,6 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; CalendarBox, ComparisonBox, LoadingBox, - PhysicsSimulationBox, SchemaRowBox, ImportElementBox, MapPushpinBox, diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index b04b1ae65..331ee1707 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -254,7 +254,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?.[fieldKey+alternate], StrCast(doc?.['backgroundColor' +alternate], isCaption ? 'rgba(0,0,0,0.4)' : '')); - if (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc) docColor = StrCast(doc._backgroundColor,docColor) + if (!docColor && doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc) docColor = StrCast(doc._backgroundColor,docColor) // prettier-ignore switch (layoutDoc?.type) { case DocumentType.PRESELEMENT: docColor = docColor || ""; break; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 20ec2f151..e6acff061 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -107,7 +107,6 @@ export class SchemaCellField extends ObservableReactComponent this._props.GetValue(), fieldVal => { - console.log('Update: ' + this._props.Document.title, this._props.fieldKey, fieldVal); this._unrenderedContent = fieldVal ?? ''; this.finalizeEdit(false, false, false); } @@ -127,7 +126,6 @@ export class SchemaCellField extends ObservableReactComponent disposer?.()); this.finalizeEdit(false, true, false); diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index e77cde431..a49c69be3 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -18,6 +18,7 @@ import { InkingStroke } from '../InkingStroke'; import './DiagramBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; +import { Tooltip } from '@mui/material'; /** * this is a class for the diagram box doc type that can be found in the tools section of the side bar */ @@ -208,7 +209,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { - (this._showCode = !this._showCode))} /> + + (this._showCode = !this._showCode))} /> +
{this._showCode ? ( diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index aab8a183a..47c5734f7 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -23,7 +23,6 @@ interface HTMLtagProps { htmltag: string; onClick?: ScriptField; onInput?: ScriptField; - scaling: number; children?: JSX.Element[]; } @@ -43,7 +42,7 @@ interface HTMLtagProps { export class HTMLtag extends React.Component { click = () => { const clickScript = this.props.onClick as Opt; - clickScript?.script.run({ this: this.props.Document, scale: this.props.scaling }); + clickScript?.script.run({ this: this.props.Document }); }; onInput = (e: React.FormEvent) => { const onInputScript = this.props.onInput as Opt; @@ -56,7 +55,6 @@ export class HTMLtag extends React.Component { 'dragStarting', 'dragEnding', 'htmltag', - 'scaling', 'Document', 'key', 'onInput', @@ -65,7 +63,7 @@ export class HTMLtag extends React.Component { ]).omit; const replacer = (match: string, expr: string) => // bcz: this executes a script to convert a property expression string: { script } into a value - (ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: this.props.Document, scale: this.props.scaling }).result as string) || ''; + (ScriptField.MakeFunction(expr, { this: Doc.name })?.script.run({ this: this.props.Document }).result as string) || ''; Object.keys(divKeys).forEach((prop: string) => { const p = (this.props as unknown as { [key: string]: string })[prop] as string; style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer); @@ -166,12 +164,11 @@ export class DocumentContentsView extends ObservableReactComponent[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer); // replace HTML with corresponding HTML tag as in: becomes - const replacer2 = (match: string, p1: string) => ` ` with as in: becomes const replacer3 = (/* match: any, p1: string, offset: any, string: any */) => `; } // prettier-ignore @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) as string ?? ""; } // prettier-ignore @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) as number ?? 0; } // prettier-ignore diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 017ef7191..5b06e9fc5 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -148,9 +148,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { ); const { layoutDoc } = this; this._disposers.path = reaction( - () => ({ nativeSize: this.nativeSize, width: NumCast(this.layoutDoc._width) }), - ({ nativeSize, width }) => { - if ((layoutDoc === this.layoutDoc && !this.layoutDoc._layout_nativeDimEditable) || !this.layoutDoc._height) { + () => ({ nativeSize: this.nativeSize, width: NumCast(this.layoutDoc._width), height: this.layoutDoc._height }), + ({ nativeSize, width, height }) => { + if ((layoutDoc === this.layoutDoc && !this.layoutDoc._layout_nativeDimEditable) || !height) { this.layoutDoc._height = (width * nativeSize.nativeHeight) / nativeSize.nativeWidth; } }, @@ -834,14 +834,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { const file = input.files?.[0]; if (file) { const disposer = OverlayView.ShowSpinner(); - const [{ result }] = await Networking.UploadFilesToServer({ file }); - if (result instanceof Error) { - alert('Error uploading files - possibly due to unsupported file types'); - } else { - this.dataDoc[this.fieldKey] = new ImageField(result.accessPaths.agnostic.client); - !(result instanceof Error) && DocUtils.assignImageInfo(result, this.dataDoc); - } - disposer(); + DocUtils.uploadFileToDoc(file, {}, this.Document).then(doc => { + disposer(); + doc && (doc.height = undefined); + }); } else { console.log('No file selected'); } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index dc4a5a011..fc89dcbe7 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1517,7 +1517,6 @@ export namespace Doc { case DocumentType.MAP: return 'map-marker-alt'; case DocumentType.DATAVIZ: return 'chart-bar'; case DocumentType.EQUATION: return 'calculator'; - case DocumentType.SIMULATION: return 'rocket'; case DocumentType.CONFIG: return 'folder-closed'; default: } -- cgit v1.2.3-70-g09d2