From 7e4d793eaa7e5b6b564355a11fa02a5611645f20 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 21 Mar 2025 18:58:21 -0400 Subject: trying to improve how data / layout / root and templtae docs are accessed. --- src/client/util/CalendarManager.tsx | 11 +++-------- src/client/util/CurrentUserUtils.ts | 17 ++++++++--------- src/client/util/DictationManager.ts | 6 ++---- src/client/util/DocumentManager.ts | 11 +++-------- src/client/util/DragManager.ts | 5 +++-- src/client/util/History.ts | 2 +- src/client/util/Import & Export/ImageUtils.ts | 14 ++++++-------- 7 files changed, 26 insertions(+), 40 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index d28b3a2c9..a0db4e32e 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -8,7 +8,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import Select from 'react-select'; import { Doc, DocListCast } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { StrCast } from '../../fields/Types'; import { Docs } from '../documents/Documents'; import { MainViewModal } from '../views/MainViewModal'; @@ -51,8 +50,6 @@ export class CalendarManager extends ObservableReactComponent { @observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the target doc @observable private dialogueBoxOpacity = 1; // 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 private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars?.data); @@ -97,7 +94,6 @@ export class CalendarManager extends ObservableReactComponent { }), 500 ); - this.layoutDocAcls = false; }); constructor(props: object) { @@ -122,9 +118,8 @@ export class CalendarManager extends ObservableReactComponent { // TODO: Make undoable private addToCalendar = () => { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar + const targetDoc = docs[0]; // doc to add to calendar - console.log(targetDoc); if (targetDoc) { let calendar: Doc; if (this.creationType === 'new-calendar') { @@ -234,7 +229,7 @@ export class CalendarManager extends ObservableReactComponent { @computed get calendarInterface() { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; + const targetDoc = docs[0]; return (
{
Select a date range:
- this.setSelectedDateRange(v)} /> + v && this.setSelectedDateRange(v)} />
{this.createButtonActive && ( diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 21e1d3e12..924041552 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -3,7 +3,6 @@ import { reaction, runInAction } from "mobx"; import * as rp from 'request-promise'; import { ClientUtils, OmitKeys } from "../../ClientUtils"; import { Doc, DocListCast, DocListCastAsync, FieldType, Opt } from "../../fields/Doc"; -import { DocData } from "../../fields/DocSymbols"; import { InkEraserTool, InkInkTool, InkProperty, InkTool } from "../../fields/InkField"; import { List } from "../../fields/List"; import { PrefetchProxy } from "../../fields/Proxy"; @@ -323,10 +322,10 @@ export class CurrentUserUtils { type: 'scatter' }`); const slide = Docs.Create.TextDocument("", opts); - slide[DocData].text = rtfield; - slide[DocData].layout_textPainted = ``; - slide[DocData]._type_collection = CollectionViewType.Freeform; - slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); + slide.$text = rtfield; + slide.$layout_textPainted = ``; + slide.$type_collection = CollectionViewType.Freeform; + slide._onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); return slide; } const mermaidsApi = () => { @@ -374,10 +373,10 @@ pie title Minerals in my tap water "Potassium" : 50 "Magnesium" : 10.01`); const slide = Docs.Create.TextDocument("", opts); - slide[DocData].text = rtfield; - slide[DocData].layout_textPainted = ``; - slide[DocData]._type_collection = CollectionViewType.Freeform; - slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); + slide.$text = rtfield; + slide.$layout_textPainted = ``; + slide.$_type_collection = CollectionViewType.Freeform; + slide._onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); return slide; } plotlyApi(); mermaidsApi(); diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 897366757..44fbda319 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -2,7 +2,6 @@ import * as interpreter from 'words-to-numbers'; import { ClientUtils } from '../../ClientUtils'; import { Doc, Opt } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { RichTextField } from '../../fields/RichTextField'; import { listSpec } from '../../fields/Schema'; @@ -339,13 +338,12 @@ export namespace DictationManager { { action: (target: DocumentView) => { const newBox = Docs.Create.TextDocument('', { _width: 400, _height: 200, title: 'My Outline', _layout_autoHeight: true }); - const proto = newBox[DocData]; const prompt = 'Press alt + r to start dictating here...'; const head = 3; const anchor = head + prompt.length; const proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"ordered_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`; - proto.data = new RichTextField(proseMirrorState, prompt); - proto.backgroundColor = '#eeffff'; + newBox.$data = new RichTextField(proseMirrorState, prompt); + newBox.$backgroundColor = '#eeffff'; target.props.addDocTab(newBox, OpenWhere.addRight); }, }, diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index e33449782..5ce005811 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -2,7 +2,6 @@ import { Howl } from 'howler'; import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx'; import { Doc, Opt } from '../../fields/Doc'; import { Animation, DocData } from '../../fields/DocSymbols'; -import { Id } from '../../fields/FieldSymbols'; import { listSpec } from '../../fields/Schema'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { AudioField } from '../../fields/URLField'; @@ -108,16 +107,16 @@ export class DocumentManager { }); // gets all views - public getDocumentViewsById(id: string) { + public getAllDocumentViews(doc: Doc) { const toReturn: DocumentView[] = []; DocumentManager.Instance.DocumentViews.forEach(view => { - if (view.Document[Id] === id) { + if (view.Document === doc) { toReturn.push(view); } }); if (toReturn.length === 0) { DocumentManager.Instance.DocumentViews.forEach(view => { - if (view.Document[DocData]?.[Id] === id) { + if (view.Document[DocData] === doc) { toReturn.push(view); } }); @@ -125,10 +124,6 @@ export class DocumentManager { return toReturn; } - public getAllDocumentViews(doc: Doc) { - return this.getDocumentViewsById(doc[Id]); - } - public getDocumentView(target: Doc | undefined, preferredCollection?: DocumentView): DocumentView | undefined { const docViewArray = DocumentManager.Instance.DocumentViews; const passes = !target ? [] : preferredCollection ? [preferredCollection, undefined] : [undefined]; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 2a7859f09..e2e4c0fe4 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -280,11 +280,12 @@ export namespace DragManager { export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: FieldType }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) { const finishDrag = (e: DragCompleteEvent) => { const bd = Docs.Create.ButtonDocument({ toolTip: title, z: 1, _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) }); + const bdData = bd[DocData]; params.forEach(p => { - Object.keys(vars).indexOf(p) !== -1 && (bd[DocData][p] = new PrefetchProxy(vars[p] as Doc)); + Object.keys(vars).indexOf(p) !== -1 && (bdData[p] = new PrefetchProxy(vars[p] as Doc)); }); // copy all "captured" arguments into document parameterfields initialize?.(bd); - bd[DocData]['onClick-paramFieldKeys'] = new List(params); + bd.$onClick_paramFieldKeys = new List(params); e.docDragData && (e.docDragData.droppedDocuments = [bd]); return e; }; diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 9728e3177..0df0ec337 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -94,7 +94,7 @@ export namespace HistoryUtil { } if (Array.isArray(value)) { } else if (parser === true || parser === 'json') { - value = JSON.parse(value); + value = value === 'undefined' ? undefined : JSON.parse(value); } else if (parser === 'none') { } else { value = parser(value); diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts index 43807397f..9c32ca25a 100644 --- a/src/client/util/Import & Export/ImageUtils.ts +++ b/src/client/util/Import & Export/ImageUtils.ts @@ -1,6 +1,5 @@ import { ClientUtils } from '../../../ClientUtils'; import { Doc } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; @@ -16,13 +15,12 @@ export namespace ImageUtils { export const AssignImgInfo = (document: Doc, data?: Upload.InspectionResults) => { if (data) { data.nativeWidth && (document._height = (NumCast(document._width) * data.nativeHeight) / data.nativeWidth); - const proto = document[DocData]; - const field = Doc.LayoutFieldKey(document); - proto[`${field}_nativeWidth`] = data.nativeWidth; - proto[`${field}_nativeHeight`] = data.nativeHeight; - proto[`${field}_path`] = data.source; - proto[`${field}_exif`] = JSON.stringify(data.exifData.data); - proto[`${field}_contentSize`] = data.contentSize ? data.contentSize : undefined; + const field = '$' + Doc.LayoutFieldKey(document); + document[`${field}_nativeWidth`] = data.nativeWidth; + document[`${field}_nativeHeight`] = data.nativeHeight; + document[`${field}_path`] = data.source; + document[`${field}_exif`] = JSON.stringify(data.exifData.data); + document[`${field}_contentSize`] = data.contentSize ? data.contentSize : undefined; } return document; }; -- cgit v1.2.3-70-g09d2 From bc308b888f41e8789f1b9f522ced46e68e726862 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 21 Mar 2025 19:24:06 -0400 Subject: from last --- src/client/documents/DocUtils.ts | 4 ++-- src/client/util/CalendarManager.tsx | 5 +++-- src/client/util/CurrentUserUtils.ts | 4 ++-- src/client/views/DocComponent.tsx | 2 +- src/client/views/PinFuncs.ts | 4 ++-- src/client/views/PropertiesButtons.tsx | 2 +- src/client/views/PropertiesView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/fields/Doc.ts | 4 +--- 9 files changed, 17 insertions(+), 18 deletions(-) (limited to 'src/client/util') diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 13f6f6920..b0170a192 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -383,8 +383,8 @@ export namespace DocUtils { const newDoc = DocUtils.copyDragFactory(dragDoc); if (newDoc) { newDoc._author = ClientUtils.CurrentUserEmail(); - newDoc._x = x; - newDoc._y = y; + newDoc.x = x; + newDoc.y = y; newDoc.$backgroundColor = Doc.UserDoc().textBackgroundColor; DocumentView.SetSelectOnLoad(newDoc); if (pivotField) { diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index a0db4e32e..3357e5d59 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -17,6 +17,7 @@ import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import './CalendarManager.scss'; import { SnappingManager } from './SnappingManager'; import { CalendarDate, DateValue } from '@internationalized/date'; +import { DocData } from '../../fields/DocSymbols'; // import 'react-date-range/dist/styles.css'; // import 'react-date-range/dist/theme/default.css'; @@ -118,7 +119,7 @@ export class CalendarManager extends ObservableReactComponent { // TODO: Make undoable private addToCalendar = () => { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = docs[0]; // doc to add to calendar + const targetDoc = docs[0]?.[DocData]; if (targetDoc) { let calendar: Doc; @@ -229,7 +230,7 @@ export class CalendarManager extends ObservableReactComponent { @computed get calendarInterface() { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = docs[0]; + const targetDoc = docs[0]?.[DocData]; return (
`; slide.$type_collection = CollectionViewType.Freeform; - slide._onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); + slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); return slide; } const mermaidsApi = () => { @@ -376,7 +376,7 @@ pie title Minerals in my tap water slide.$text = rtfield; slide.$layout_textPainted = ``; slide.$_type_collection = CollectionViewType.Freeform; - slide._onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); + slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); return slide; } plotlyApi(); mermaidsApi(); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 064906530..79a0cc602 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -42,7 +42,7 @@ export function DocComponent

() { * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. */ @computed get layoutDoc() { - return this._props.LayoutTemplateString ? this.Document : Doc.Layout(this._props.Document, this._props.LayoutTemplate?.()); + return this._props.LayoutTemplateString ? this._props.Document : Doc.Layout(this._props.Document, this._props.LayoutTemplate?.()); } /** diff --git a/src/client/views/PinFuncs.ts b/src/client/views/PinFuncs.ts index 1ab8575a8..d756830da 100644 --- a/src/client/views/PinFuncs.ts +++ b/src/client/views/PinFuncs.ts @@ -76,8 +76,8 @@ export function PinDocView(pinDocIn: Doc, pinProps: PinProps, targetDoc: Doc) { pinDoc.config_data = Field.Copy(targetDoc[fkey]); } if (pinProps.pinData.dataannos) { - const fieldKey = Doc.LayoutFieldKey(targetDoc); - pinDoc.config_annotations = new List(DocListCast(targetDoc['$' + fieldKey + '_annotations']).filter(doc => !doc.layout_unrendered)); + const fieldKey = '$' + Doc.LayoutFieldKey(targetDoc) + +'_annotations'; + pinDoc.config_annotations = new List(DocListCast(targetDoc[fieldKey]).filter(doc => !doc.layout_unrendered)); } if (pinProps.pinData.inkable) { pinDoc.config_fillColor = targetDoc.fillColor; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 2b4fe478e..a1e8fe7ba 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -131,7 +131,7 @@ export class PropertiesButtons extends React.Component { on => `${on ? 'Flashcard enabled' : 'Flashcard disabled'} `, () => , (dv, doc) => { - const on = !!doc.onPaint; + const on = !!doc.$onPaint; doc.$onPaint = on ? undefined : ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, { documentView: 'any' }); doc.$layout_textPainted = on ? undefined : ``; } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c72f958fc..b95553c4e 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -891,7 +891,7 @@ export class PropertiesView extends ObservableReactComponent { doc.$color = value || undefined; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index fdaf13733..46bd076d4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -143,10 +143,10 @@ export class DocumentViewInternal extends DocComponent Date: Sun, 23 Mar 2025 10:27:28 -0400 Subject: updated more [DocData] to .$ things --- src/client/util/CalendarManager.tsx | 5 +-- src/client/util/LinkManager.ts | 6 +-- src/client/views/DocComponent.tsx | 9 ++-- src/client/views/PropertiesDocContextSelector.tsx | 2 +- src/client/views/PropertiesView.tsx | 8 +--- src/client/views/SidebarAnnos.tsx | 9 ++-- src/client/views/StyleProviderQuiz.tsx | 8 ++-- src/client/views/TagsView.tsx | 33 +++++++-------- .../views/collections/CollectionDockingView.tsx | 6 +-- .../collections/CollectionMasonryViewFieldRow.tsx | 3 +- src/client/views/collections/CollectionMenu.tsx | 3 +- .../views/collections/CollectionNoteTakingView.tsx | 2 +- .../collections/CollectionNoteTakingViewColumn.tsx | 2 +- .../collections/CollectionStackedTimeline.tsx | 8 ++-- .../views/collections/CollectionStackingView.tsx | 5 +-- src/client/views/collections/CollectionSubView.tsx | 12 +++++- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 5 +-- .../CollectionFreeFormInfoUI.tsx | 11 +++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 25 ++++++----- .../collectionFreeForm/FaceCollectionBox.tsx | 4 +- .../collectionFreeForm/ImageLabelBox.tsx | 19 ++++----- .../collections/collectionFreeForm/MarqueeView.tsx | 19 ++++----- src/client/views/global/globalScripts.ts | 49 +++++++++------------- src/client/views/nodes/AudioBox.tsx | 2 +- src/client/views/nodes/ComparisonBox.tsx | 10 ++--- .../views/nodes/DataVizBox/components/TableBox.tsx | 4 +- src/client/views/nodes/DiagramBox.tsx | 5 +-- src/client/views/nodes/DocumentView.tsx | 14 +++---- src/client/views/nodes/ImageBox.tsx | 42 +++++++++---------- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/client/views/nodes/LinkBox.tsx | 6 +-- src/client/views/nodes/LinkDescriptionPopup.tsx | 3 +- src/client/views/nodes/PDFBox.tsx | 17 ++++---- .../views/nodes/RecordingBox/RecordingBox.tsx | 3 +- src/client/views/nodes/VideoBox.tsx | 48 ++++++++++----------- src/client/views/nodes/calendarBox/CalendarBox.tsx | 2 +- .../nodes/chatbot/chatboxcomponents/ChatBox.tsx | 6 +-- .../views/nodes/formattedText/EquationView.tsx | 5 +-- src/client/views/nodes/imageEditor/ImageEditor.tsx | 9 ++-- src/client/views/nodes/trails/PresBox.tsx | 9 ++-- src/client/views/smartdraw/SmartDrawHandler.tsx | 21 +++++----- src/client/views/smartdraw/StickerPalette.tsx | 28 ++++++------- src/fields/Doc.ts | 25 ++++++----- src/fields/ScriptField.ts | 3 +- 45 files changed, 243 insertions(+), 276 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index 3357e5d59..1a5a5f889 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -17,7 +17,6 @@ import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import './CalendarManager.scss'; import { SnappingManager } from './SnappingManager'; import { CalendarDate, DateValue } from '@internationalized/date'; -import { DocData } from '../../fields/DocSymbols'; // import 'react-date-range/dist/styles.css'; // import 'react-date-range/dist/theme/default.css'; @@ -119,7 +118,7 @@ export class CalendarManager extends ObservableReactComponent { // TODO: Make undoable private addToCalendar = () => { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = docs[0]?.[DocData]; + const targetDoc = docs[0]; if (targetDoc) { let calendar: Doc; @@ -230,7 +229,7 @@ export class CalendarManager extends ObservableReactComponent { @computed get calendarInterface() { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = docs[0]?.[DocData]; + const targetDoc = docs[0]; return (
!Doc.IsSystem(doc)); + // const strings = isFiltered.map(doc => StrCast(doc.title) + ' ' + (Doc.IsDataProto(doc) ? '(data)' : '(embedding)')); //Doc.MyDockedBtns.linearView_IsOpen && strings.sort().forEach((str, i) => console.log(i.toString() + ' ' + str)); rp.post(ClientUtils.prepend('/setCacheDocumentIds'), { diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 79a0cc602..a311f6436 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -49,7 +49,7 @@ export function DocComponent

() { * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this.Document[DocData]; + return this._props.Document[DocData]; } } return Component; @@ -93,7 +93,7 @@ export function ViewBoxBaseComponent

() { * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this.Document.isTemplateForField || this.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this.Document[DocData]) : this.Document[DocData]; + return this._props.Document.isTemplateForField || this._props.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._props.Document[DocData]) : this._props.Document[DocData]; } /** @@ -151,7 +151,7 @@ export function ViewBoxAnnotatableComponent

() { * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this.Document.isTemplateForField || this.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this.Document[DocData]) : this.Document[DocData]; + return this._props.Document.isTemplateForField || this._props.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._props.Document[DocData]) : this._props.Document[DocData]; } /** @@ -225,8 +225,7 @@ export function ViewBoxAnnotatableComponent

() { if ([AclAugment, AclEdit, AclAdmin].includes(effectiveAcl)) { added.forEach(adoc => { adoc._dragOnlyWithinContainer = undefined; - if (annotationKey ?? this._annotationKeySuffix()) adoc[DocData].annotationOn = this.Document; - else adoc[DocData].annotationOn = undefined; + adoc.$annotationOn = (annotationKey ?? this._annotationKeySuffix()) ? this.Document : undefined; Doc.SetContainer(adoc, this.Document); inheritParentAcls(targetDataDoc, adoc, true); }); diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx index f494ff16a..ee6486a9c 100644 --- a/src/client/views/PropertiesDocContextSelector.tsx +++ b/src/client/views/PropertiesDocContextSelector.tsx @@ -26,7 +26,7 @@ export class PropertiesDocContextSelector extends ObservableReactComponent embedding.embedContainer && embedding.embedContainer instanceof Doc).reduce((set, embedding) => set.add(Cast(embedding.embedContainer, Doc, null)), new Set()); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index b95553c4e..7e9cd002b 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -181,7 +181,7 @@ export class PropertiesView extends ObservableReactComponent { const layoutDoc = this.selectedLayoutDoc; - if (layoutDoc && this.dataDoc) { + if (layoutDoc) { return Math.max( 70, Math.min( @@ -308,11 +308,7 @@ export class PropertiesView extends ObservableReactComponent data.split(':')[0]) .filter(data => !filterExlusions?.includes(data.split(':')[0])) .map(data => { - const key = data.split(':')[0]; + const key = '$'+data.split(':')[0]; const val = Field.Copy(this.allMetadata.get(key)); - target[DocData][key] = val; + target[key] = val; return { type: 'dashField', attrs: { fieldKey: key, docId: '', hideKey: false, hideValue: false, editable: true }, @@ -98,7 +97,7 @@ export class SidebarAnnos extends ObservableReactComponent { - const input = StrCast(doc[DocData].title); + const input = StrCast(doc.$title); if (imgQuizMode(img) == quizMode.SMART && input) { const questionText = 'Question: What was labeled in this image?'; const rubricText = ' Rubric: ' + StrCast(doc.quiz); @@ -275,8 +275,8 @@ export namespace styleProviderQuiz { function redo(img: ImageBox) { imgQuizBoxes(img).forEach(doc => { - doc[DocData].title = ''; - doc.backgroundColor = '#e4e4e4'; + doc.$title = ''; + doc.$backgroundColor = '#e4e4e4'; }); } diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index 93d6fb684..7d2a6be5e 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -72,7 +72,7 @@ export class TagItem extends ObservableReactComponent { const newTagCol = new Doc(); newTagCol.title = tag; newTagCol.collections = new List(); - newTagCol[DocData].docs = new List(); + newTagCol.$docs = new List(); Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard, 'myTagCollections', newTagCol); return newTagCol; @@ -82,7 +82,7 @@ export class TagItem extends ObservableReactComponent { * @param tag tag string * @returns An array of documents that contain the tag. */ - public static allDocsWithTag = (tag: string) => DocListCast(TagItem.findTagCollectionDoc(tag)?.[DocData].docs); + public static allDocsWithTag = (tag: string) => DocListCast(TagItem.findTagCollectionDoc(tag)?.$docs); public static docHasTag = (doc: Doc, tag: string) => StrListCast(doc?.tags).includes(tag); /** @@ -95,11 +95,11 @@ export class TagItem extends ObservableReactComponent { // If the document is of type COLLECTION, make it a smart collection, otherwise, add the tag to the document. if (doc.type === DocumentType.COL && !doc.annotationOn) { - Doc.AddDocToList(tagCollection[DocData], 'collections', doc); + Doc.AddDocToList(tagCollection, 'collections', doc); // Iterate through the tag Doc collections and add a copy of the document to each collection - for (const cdoc of DocListCast(tagCollection[DocData].docs)) { - if (!DocListCast(doc[DocData].data).find(d => Doc.AreProtosEqual(d, cdoc))) { + for (const cdoc of DocListCast(tagCollection.$docs)) { + if (!DocListCast(doc.$data).find(d => Doc.AreProtosEqual(d, cdoc))) { const newEmbedding = Doc.MakeEmbedding(cdoc); Doc.AddDocToList(doc[DocData], 'data', newEmbedding); Doc.SetContainer(newEmbedding, doc); @@ -111,7 +111,7 @@ export class TagItem extends ObservableReactComponent { // Iterate through the tag document's collections and add a copy of the document to each collection for (const collection of DocListCast(tagCollection.collections)) { - if (!DocListCast(collection[DocData].data).find(d => Doc.AreProtosEqual(d, doc))) { + if (!DocListCast(collection.$data).find(d => Doc.AreProtosEqual(d, doc))) { const newEmbedding = Doc.MakeEmbedding(doc); Doc.AddDocToList(collection[DocData], 'data', newEmbedding); Doc.SetContainer(newEmbedding, collection); @@ -119,8 +119,8 @@ export class TagItem extends ObservableReactComponent { } } - if (!doc[DocData].tags) doc[DocData].tags = new List(); - const tagList = doc[DocData].tags as List; + if (!doc.$tags) doc.$tags = new List(); + const tagList = doc.$tags as List; if (!tagList.includes(tag)) tagList.push(tag); }; @@ -131,22 +131,22 @@ export class TagItem extends ObservableReactComponent { * @param tagDoc doc that collections the Docs with the tag */ public static removeTagFromDoc = (doc: Doc, tag: string, tagDoc?: Doc) => { - if (doc[DocData].tags) { + if (doc.$tags) { if (doc.type === DocumentType.COL) { tagDoc && Doc.RemoveDocFromList(tagDoc[DocData], 'collections', doc); for (const cur_doc of TagItem.allDocsWithTag(tag)) { - doc[DocData].data = new List(DocListCast(doc[DocData].data).filter(d => !Doc.AreProtosEqual(cur_doc, d))); + doc.$data = new List(DocListCast(doc.$data).filter(d => !Doc.AreProtosEqual(cur_doc, d))); } } else { tagDoc && Doc.RemoveDocFromList(tagDoc[DocData], 'docs', doc); for (const collection of DocListCast(tagDoc?.collections)) { - collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(d => !Doc.AreProtosEqual(doc, d))); + collection.$data = new List(DocListCast(collection.$data).filter(d => !Doc.AreProtosEqual(doc, d))); } } } - doc[DocData].tags = new List(StrListCast(doc[DocData].tags).filter(label => label !== tag)); + doc.$tags = new List(StrListCast(doc.$tags).filter(label => label !== tag)); }; private _ref: React.RefObject; @@ -171,11 +171,10 @@ export class TagItem extends ObservableReactComponent { // Create a new collection and set up configurations. const newCollection = ((doc: Doc) => { - const docData = doc[DocData]; - docData.data = new List(newEmbeddings); - docData.title = this._props.tag; - docData.tags = new List([this._props.tag]); - docData.freeform_fitContentsToBox = true; + doc.$data = new List(newEmbeddings); + doc.$title = this._props.tag; + doc.$tags = new List([this._props.tag]); + doc.$freeform_fitContentsToBox = true; doc._freeform_panX = doc._freeform_panY = 0; doc._width = 900; doc._height = 900; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index a45b37f43..12a131deb 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -5,7 +5,7 @@ import * as ReactDOM from 'react-dom/client'; import ResizeObserver from 'resize-observer-polyfill'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, incrementTitleCopy, returnTrue, UpdateIcon } from '../../../ClientUtils'; import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc'; -import { AclAdmin, AclEdit, DocData } from '../../../fields/DocSymbols'; +import { AclAdmin, AclEdit } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; @@ -481,7 +481,7 @@ export class CollectionDockingView extends CollectionSubView() { Array.from(cloned.map.entries()).forEach(entry => { json = json.replace(entry[0], entry[1][Id]); }); - cloned.clone[DocData].dockingConfig = json; + cloned.clone.$dockingConfig = json; return DashboardView.openDashboard(cloned.clone); } const matches = json.match(/"documentId":"[a-z0-9-]+"/g); @@ -495,7 +495,7 @@ export class CollectionDockingView extends CollectionSubView() { const newtab = origtabdocs.length ? Doc.MakeCopy(origtab, true, undefined, true) : Doc.MakeEmbedding(origtab); const newtabdocs = origtabdocs.map(origtabdoc => Doc.MakeEmbedding(origtabdoc)); if (newtabdocs.length) { - newtab[DocData].data = new List(newtabdocs); + newtab.$data = new List(newtabdocs); newtabdocs.forEach(ntab => Doc.SetContainer(ntab, newtab)); } json = json.replace(origtab[Id], newtab[Id]); diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 996626575..4fe73895e 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -5,7 +5,6 @@ import * as React from 'react'; import { returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../ClientUtils'; import { emptyFunction, numberRange } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { ScriptField } from '../../../fields/ScriptField'; import { Docs } from '../../documents/Documents'; @@ -164,7 +163,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent { - this.target[DocData].data = new List(source); + this.target.$data = new List(source); }, ''), initialize: emptyFunction, }; diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index c499bd288..4650727eb 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -441,7 +441,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { if ((e.ctrlKey || fieldProps.Document._createDocOnCR) && ['Enter'].includes(e.key)) { e.stopPropagation?.(); const newDoc = Doc.MakeCopy(fieldProps.Document, true); - newDoc[DocData].text = undefined; + newDoc.$text = undefined; DocumentView.SetSelectOnLoad(newDoc); return this.addDocument?.(newDoc); } diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index 40b3f9ef2..df9b5a1eb 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -157,7 +157,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); if (this._props.headingObject) { - // this._props.docList.forEach(d => (d[DocData][this._props.pivotField] = undefined)); + // this._props.docList.forEach(d => (d['$'+this._props.pivotField] = undefined)); colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1); this._props.resizeColumns(colHdrData); } diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index a7a9f2114..0836cce38 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -432,8 +432,8 @@ export class CollectionStackedTimeline extends CollectionSubView { - this._props.mark[DocData].title = ComputedField.MakeFunction( - `["${this._props.endTag}"] ? "#" + formatToTime(this["${this._props.startTag}"]) + "-" + formatToTime(this["${this._props.endTag}"]) : "#" + formatToTime(this["${this._props.startTag}"]` - ); + this._props.mark.$title = ComputedField.MakeFunction(`["${this._props.endTag}"] ? "#" + formatToTime(this["${this._props.startTag}"]) + "-" + formatToTime(this["${this._props.endTag}"]) : "#" + formatToTime(this["${this._props.startTag}"]`); }; // context menu contextMenuItems = () => { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 392d85af3..9972fe03d 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -5,7 +5,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ClientUtils, DivHeight, returnNone, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils'; import { Doc, Opt } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; @@ -316,11 +315,11 @@ export class CollectionStackingView extends CollectionSubView([]) : undefined; + newDoc['$' + Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List([]) : undefined; if (layoutFieldKey !== 'layout' && fieldProps.Document[layoutFieldKey] instanceof Doc) { newDoc[layoutFieldKey] = fieldProps.Document[layoutFieldKey]; } - newDoc[DocData].text = undefined; + newDoc.$text = undefined; DocumentView.SetSelectOnLoad(newDoc); return this.addDocument?.(newDoc); } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 655894e40..29caead5b 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -9,7 +9,7 @@ import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, DateCast, NumCast, ScriptCast, StrCast, toList } from '../../../fields/Types'; +import { BoolCast, Cast, DateCast, DocCast, NumCast, ScriptCast, StrCast, toList } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; @@ -85,6 +85,9 @@ export function CollectionSubView() { constructor(props: X & SubCollectionViewProps) { super(props); makeObservable(this); + console.log(`propsTitle: ${this._props.Document.title} DocTitle: ${this.Document.title} LayoutTitle:${this.layoutDoc.title} DataTitle:${this.dataDoc.title}`); + console.log(`tempTitle: ${this._props.TemplateDataDocument?.title} LayouTResolve: ${DocCast(this.layoutDoc.resolvedDataDoc)?.title} propDocResolve: ${DocCast(this._props.Document.resolvedDataDoc)?.title}`); + console.log('Children:', this.childDocs, this.childLayoutPairs); } @observable _focusFilters: Opt = undefined; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it @@ -108,7 +111,12 @@ export function CollectionSubView() { } get dataDoc() { - return this._props.TemplateDataDocument instanceof Doc && this.Document.isTemplateForField ? Doc.GetProto(this._props.TemplateDataDocument) : this.Document.resolvedDataDoc ? this.Document : this.Document[DocData]; // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template + console.log(this._props.Document.title + ' isTemplate: ' + this.layoutDoc.isTemplateForField); + return this._props.TemplateDataDocument instanceof Doc && this.layoutDoc.isTemplateForField // + ? this._props.TemplateDataDocument[DocData] + : this.layoutDoc.resolvedDataDoc + ? this._props.Document + : this.Document[DocData]; // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template } get childContainerViewPath() { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index cc56a8ff9..2d2c0fce5 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -347,7 +347,7 @@ export class TabDocView extends ObservableReactComponent { undoable(() => { const target = e.currentTarget as unknown as { value: string }; titleEle.size = target?.value.length + 3; - doc[DocData].title = target?.value ?? ''; + doc.$title = target?.value ?? ''; }, 'edit tab title')(); }; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 6208905fe..d6a19e88e 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -372,9 +372,8 @@ export class TreeView extends ObservableReactComponent { _width: 1000, _height: 10, }); - const bulletData = bullet[DocData]; - bulletData.title = ComputedField.MakeFunction('this.text?.Text'); - bulletData.data = new List([]); + bullet.$title = ComputedField.MakeFunction('this.text?.Text'); + bullet.$data = new List([]); DocumentView.addViewRenderedCb(bullet, dv => dv.ComponentView?.setFocus?.()); return bullet; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index 8b9a3e0ec..35c6d30fe 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -1,16 +1,15 @@ import { makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, DocListCast, FieldType, FieldResult } from '../../../../fields/Doc'; +import { Doc, DocListCast, FieldResult, FieldType } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { StrCast } from '../../../../fields/Types'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton'; import { TopBar } from '../../topbar/TopBar'; import { CollectionFreeFormInfoState, InfoState, StateEntryFunc, infoState } from './CollectionFreeFormInfoState'; -import './CollectionFreeFormView.scss'; -import { DocData } from '../../../../fields/DocSymbols'; import { CollectionFreeFormView } from './CollectionFreeFormView'; +import './CollectionFreeFormView.scss'; export interface CollectionFreeFormInfoUIProps { Document: Doc; @@ -41,7 +40,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent {this._currState = val;}); } // prettier-ignore componentWillUnmount(): void { - this._props.Document[DocData].backgroundColor = this._originalbackground; + this._props.Document.$backgroundColor = this._originalbackground; } setCurrState = (state: infoState) => { @@ -52,9 +51,9 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent { - this._originalbackground = StrCast(this._props.Document[DocData].backgroundColor); + this._originalbackground = StrCast(this._props.Document.$backgroundColor); // state entry functions - // const setBackground = (colour: string) => () => {this._props.Document[DocData].backgroundColor = colour;} // prettier-ignore + // const setBackground = (colour: string) => () => {this._props.Document.$backgroundColor = colour;} // prettier-ignore // const setOpacity = (opacity: number) => () => {this._props.LayoutDoc.opacity = opacity;} // prettier-ignore // arc transition trigger conditions const firstDoc = () => (this._props.childDocs().length ? this._props.childDocs()[0] : undefined); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 89aa53c35..6030e146c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -561,7 +561,7 @@ export class CollectionFreeFormView extends CollectionSubView { - inkDoc[DocData][field] = stroke.dataDoc[field]; + inkDoc['$' + field] = stroke.dataDoc[field]; }); this.addDocument(inkDoc); }); @@ -1260,15 +1260,14 @@ export class CollectionFreeFormView extends CollectionSubView { - const docData = doc[DocData]; - docData.title = opts.text; - docData._width = opts.size; - docData.ai_drawing_input = opts.text; - docData.ai_drawing_complexity = opts.complexity; - docData.ai_drawing_colored = opts.autoColor; - docData.ai_drawing_size = opts.size; - docData.ai_drawing_data = gptRes; - docData.ai = 'gpt'; + doc.$title = opts.text; + doc.$width = opts.size; + doc.$ai_drawing_input = opts.text; + doc.$ai_drawing_complexity = opts.complexity; + doc.$ai_drawing_colored = opts.autoColor; + doc.$ai_drawing_size = opts.size; + doc.$ai_drawing_data = gptRes; + doc.$ai = 'gpt'; this._drawingContainer = doc; if (x !== undefined && y !== undefined) { [doc.x, doc.y] = this.screenToFreeformContentsXf.transformPoint(x, y); @@ -1493,7 +1492,7 @@ export class CollectionFreeFormView extends CollectionSubView { const textDoc = DocCast(fieldProps.Document.rootDocument, fieldProps.Document); const newDoc = Doc.MakeCopy(textDoc, true); - newDoc[DocData][Doc.LayoutFieldKey(newDoc, fieldProps.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style + newDoc['$' + Doc.LayoutFieldKey(newDoc, fieldProps.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style newDoc.x = NumCast(textDoc.x) + (below ? 0 : NumCast(textDoc._width) + 10); newDoc.y = NumCast(textDoc.y) + (below ? NumCast(textDoc._height) + 10 : 0); DocumentView.SetSelectOnLoad(newDoc); @@ -1686,7 +1685,7 @@ export class CollectionFreeFormView extends CollectionSubView (this.Document.isTemplateDoc || this.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); + renderCutoffProvider = computedFn((doc: Doc) => (this._props.Document.isTemplateDoc || this._props.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); doEngineLayout( poolData: Map, diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index b9f8b13a7..b40189d76 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -108,7 +108,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { if (faceAnno) { faceAnno.face && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(faceAnno, DocCast(faceAnno.face)); FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, this.Document); - faceAnno[DocData].face = this.Document[DocData]; + faceAnno.$face = this.Document[DocData]; } } }); @@ -118,7 +118,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { const imgDoc = faceAnno; faceAnno.face && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, DocCast(faceAnno.face)); FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, this.Document); - faceAnno[DocData].face = this.Document[DocData]; + faceAnno.$face = this.Document[DocData]; }); e.stopPropagation(); return true; diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index a3d9641da..c983d7c26 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { imageUrlToBase64 } from '../../../../ClientUtils'; import { Utils, numberRange } from '../../../../Utils'; import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; -import { DocData } from '../../../../fields/DocSymbols'; import { List } from '../../../../fields/List'; import { ImageCast } from '../../../../fields/Types'; import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT'; @@ -165,7 +164,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. const imageInfos = this._selectedImages.map(async doc => { - if (!doc[DocData].tags_chat) { + if (!doc.$tags_chat) { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => !hrefBase64 ? undefined : @@ -176,7 +175,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { (await Promise.all(imageInfos)).forEach(imageInfo => { if (imageInfo) { - imageInfo.doc[DocData].tags_chat = (imageInfo.doc[DocData].tags_chat as List) ?? new List(); + imageInfo.doc.$tags_chat = (imageInfo.doc.$tags_chat as List) ?? new List(); const labels = imageInfo.labels.split('\n'); labels.forEach(label => { @@ -186,7 +185,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { .replace(/^\d+\.\s*|-|f\*/, '') .replace(/^#/, '') .trim(); - (imageInfo.doc[DocData].tags_chat as List).push(hashLabel); + (imageInfo.doc.$tags_chat as List).push(hashLabel); }); } }); @@ -201,10 +200,10 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { this.startLoading(); for (const doc of this._selectedImages) { - for (let index = 0; index < (doc[DocData].tags_chat as List).length; index++) { - const label = (doc[DocData].tags_chat as List)[index]; + for (let index = 0; index < (doc.$tags_chat as List).length; index++) { + const label = (doc.$tags_chat as List)[index]; const embedding = await gptGetEmbedding(label); - doc[DocData][`tags_embedding_${index + 1}`] = new List(embedding); + doc[`$tags_embedding_${index + 1}`] = new List(embedding); } } @@ -215,13 +214,13 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // For each image, loop through the labels, and calculate similarity. Associate it with the // most similar one. this._selectedImages.forEach(doc => { - const embedLists = numberRange((doc[DocData].tags_chat as List).length).map(n => Array.from(NumListCast(doc[DocData][`tags_embedding_${n + 1}`]))); + const embedLists = numberRange((doc.$tags_chat as List).length).map(n => Array.from(NumListCast(doc[`$tags_embedding_${n + 1}`]))); const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map(l => (embedding && similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) .reduce((prev, cur) => cur.similarityScore < 0.3 || cur.similarityScore <= prev.similarityScore ? prev: cur, { label: '', similarityScore: 0, }); // prettier-ignore - doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. + doc.$data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. }); this.endLoading(); @@ -322,7 +321,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { await DocumentView.showDocument(doc, { willZoomCentered: true }); }}>

this._props.addDocTab(doc, OpenWhere.addRightKeyvalue)}> - {(doc[DocData].tags_chat as List).map(label => { + {(doc.$tags_chat as List).map(label => { return (
{label} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index ad52db496..e3f4c6605 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -165,7 +165,7 @@ export class MarqueeView extends ObservableReactComponent { - this._props.Document[DocData].icon = new ImageField(returnedfilename); + this._props.Document.$icon = new ImageField(returnedfilename); }); }) ); @@ -371,10 +371,9 @@ export class MarqueeView extends ObservableReactComponent { - const docData = doc[DocData]; - docData.data = new List(selected); - docData.isGroup = makeGroup; - docData.title = makeGroup ? 'grouping' : 'nested freeform'; + doc.$data = new List(selected); + doc.$isGroup = makeGroup; + doc.$title = makeGroup ? 'grouping' : 'nested freeform'; doc._freeform_panX = doc._freeform_panY = 0; return doc; })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); @@ -462,9 +461,9 @@ export class MarqueeView extends ObservableReactComponent { - doc[DocData].borderColor = color; - }); + else selected.forEach(doc => (doc.$borderColor = color)); } return ''; }); @@ -114,7 +108,7 @@ ScriptingGlobals.add(function setBorderColor(color?: string, checkResult?: boole ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: boolean) { const selectedViews = DocumentView.Selected(); const selectedDoc = selectedViews.lastElement()?.Document; - const defaultFill = selectedDoc?._layout_isSvg ? () => StrCast(selectedDoc[DocData].fillColor) : !Doc.ActiveTool || Doc.ActiveTool === InkTool.None ? () => StrCast(Doc.UserDoc().textBackgroundColor, 'transparent') : () => ActiveInkFillColor(); + const defaultFill = selectedDoc?._layout_isSvg ? () => StrCast(selectedDoc.$fillColor) : !Doc.ActiveTool || Doc.ActiveTool === InkTool.None ? () => StrCast(Doc.UserDoc().textBackgroundColor, 'transparent') : () => ActiveInkFillColor(); const setDefaultFill = !Doc.ActiveTool || Doc.ActiveTool === InkTool.None ? (c: string) => { Doc.UserDoc().textBackgroundColor = c; }: SetActiveInkFillColor; // prettier-ignore if (Doc.ActiveTool !== InkTool.None && !selectedViews.lastElement()?.Document._layout_isSvg) { if (checkResult) return defaultFill(); @@ -149,10 +143,7 @@ ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: b return selected.lastElement()?._backgroundColor ?? defaultFill(); } if (!selected.length) setDefaultFill(color ?? 'transparent'); - else - selected.forEach(doc => { - doc[DocData][doc._layout_isSvg ? 'fillColor' : 'backgroundColor'] = color; - }); + else selected.forEach(doc => (doc[doc._layout_isSvg ? '$fillColor' : '$backgroundColor'] = color)); } return ''; }); @@ -170,7 +161,7 @@ ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boole } if (DocumentView.Selected().length) { DocumentView.SelectedDocs().forEach(doc => { - doc[DocData].layout_headingColor = color === 'transparent' ? undefined : color; + doc.$layout_headingColor = color === 'transparent' ? undefined : color; doc.layout_showTitle = color === 'transparent' ? undefined : StrCast(doc.layout_showTitle, 'title'); }); } else { @@ -470,23 +461,23 @@ ScriptingGlobals.add(function setInkProperty(option: InkProperty, value: string // prettier-ignore const map: Map number|boolean|string|undefined; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([ [InkProperty.Mask, { - checkResult: () => ((selected?._layout_isSvg ? BoolCast(selected[DocData].stroke_isInkMask) : ActiveIsInkMask())), - setInk: (doc: Doc) => { doc[DocData].stroke_isInkMask = !doc.stroke_isInkMask; }, + checkResult: () => ((selected?._layout_isSvg ? BoolCast(selected.$stroke_isInkMask) : ActiveIsInkMask())), + setInk: (doc: Doc) => { doc.$stroke_isInkMask = !doc.stroke_isInkMask; }, setMode: () => SetActiveIsInkMask(value ? true : false) }], [InkProperty.Labels, { - checkResult: () => ((selected?._layout_isSvg ? BoolCast(selected[DocData].stroke_showLabel) : !ActiveHideTextLabels())), - setInk: (doc: Doc) => { doc[DocData].stroke_showLabel = value; }, + checkResult: () => ((selected?._layout_isSvg ? BoolCast(selected.$stroke_showLabel) : !ActiveHideTextLabels())), + setInk: (doc: Doc) => { doc.$stroke_showLabel = value; }, setMode: () => SetactiveHideTextLabels(value? false : true), }], [ InkProperty.StrokeWidth, { - checkResult: () => (selected?._layout_isSvg ? NumCast(selected[DocData].stroke_width, 1) : ActiveInkWidth()), - setInk: (doc: Doc) => { doc[DocData].stroke_width = NumCast(value); }, + checkResult: () => (selected?._layout_isSvg ? NumCast(selected.$stroke_width, 1) : ActiveInkWidth()), + setInk: (doc: Doc) => { doc.$stroke_width = NumCast(value); }, setMode: () => SetActiveInkWidth(value.toString()), }], [InkProperty.StrokeColor, { - checkResult: () => (selected?._layout_isSvg? StrCast(selected[DocData].color) : ActiveInkColor()), - setInk: (doc: Doc) => { doc[DocData].color = String(value); }, + checkResult: () => (selected?._layout_isSvg? StrCast(selected.$color) : ActiveInkColor()), + setInk: (doc: Doc) => { doc.$color = String(value); }, setMode: () => SetActiveInkColor(StrCast(value)) }], [ InkProperty.EraserWidth, { diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 25e76e2a6..e0d59cc9d 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -296,7 +296,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent() { 'Content-Type': 'application/json', }, }); - this.Document[DocData].phoneticTranscription = response.data['transcription']; + this.Document.$phoneticTranscription = response.data['transcription']; }; // context menu diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index c0c6db4d3..992fbba66 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -80,8 +80,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() const front = Docs.Create.CenteredTextCreator('question', question, {}, img); const back = Docs.Create.CenteredTextCreator('answer', answer, {}); if (useDoc) { - useDoc[DocData][frontKey] = front; - useDoc[DocData][backKey] = back; + useDoc['$' + frontKey] = front; + useDoc['$' + backKey] = back; return useDoc; } return Docs.Create.FlashcardDocument(title, front, back, { _width: 300, _height: 300 }); @@ -475,7 +475,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() axios .post( 'http://localhost:105/recognize/', // - { file: DocCast(this.Document.audio)[DocData].url }, + { file: DocCast(this.Document.audio).$url }, { headers: { 'Content-Type': 'application/json' } } ) .then(response => { @@ -520,7 +520,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() action(resp => { switch (resp && callType) { case GPTCallType.CHATCARD: - DocCast(this.dataDoc[this.backKey])[DocData].text = resp; + DocCast(this.dataDoc[this.backKey]).$text = resp; break; case GPTCallType.QUIZDOC: this._renderSide = this.backKey; @@ -618,7 +618,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() const hrefBase64 = await imageUrlToBase64(u); const response = await gptImageLabel(hrefBase64, 'Answer the following question as a short flashcard response. Do not include a label.' + (this.dataDoc.text as RichTextField)?.Text); - DocCast(this.dataDoc[this.backKey])[DocData].text = response; + DocCast(this.dataDoc[this.backKey]).$text = response; } catch (error) { console.log('Error', error); } diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 7ef4bca6b..b31a0ec1e 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -160,8 +160,8 @@ export class TableBox extends ObservableReactComponent { DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, { dragComplete: completeEv => { if (!completeEv.aborted && completeEv.annoDragData && completeEv.annoDragData.linkSourceDoc && completeEv.annoDragData.dropDocument && completeEv.linkDocument) { - completeEv.linkDocument[DocData].link_matchEmbeddings = true; - completeEv.linkDocument[DocData].stroke_startMarker = true; + completeEv.linkDocument.$link_matchEmbeddings = true; + completeEv.linkDocument.$stroke_startMarker = true; this._props.docView?.()?._props.addDocument?.(completeEv.linkDocument); } }, diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index a49c69be3..3b666bad5 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -3,7 +3,6 @@ import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { RichTextField } from '../../../fields/RichTextField'; import { Cast, DocCast, NumCast, RTFCast, StrCast } from '../../../fields/Types'; import { Gestures } from '../../../pen-gestures/GestureTypes'; @@ -46,7 +45,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { @observable _errorMessage = ''; @computed get mermaidcode() { - return StrCast(this.Document[DocData].text, RTFCast(this.Document[DocData].text)?.Text); + return StrCast(this.Document.$text, RTFCast(this.Document.$text)?.Text); } componentDidMount() { @@ -89,7 +88,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { }; setMermaidCode = undoable((res: string) => { - this.Document[DocData].text = new RichTextField( + this.Document.$text = new RichTextField( JSON.stringify({ doc: { type: 'doc', diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 46bd076d4..e9353b001 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -9,7 +9,7 @@ import { Fade, JackInTheBox } from 'react-awesome-reveal'; import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simMouseEvent, simulateMouseClick } from '../../../ClientUtils'; import { Utils, emptyFunction } from '../../../Utils'; import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc'; -import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols'; +import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocViews } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; @@ -40,6 +40,7 @@ import { FieldsDropdown } from '../FieldsDropdown'; import { ObserverJsxParser } from '../ObservableReactComponent'; import { PinProps } from '../PinFuncs'; import { StyleProp } from '../StyleProp'; +import { TagsView } from '../TagsView'; import { ViewBoxInterface } from '../ViewBoxInterface'; import { GroupActive } from './CollectionFreeFormDocumentView'; import { DocumentContentsView } from './DocumentContentsView'; @@ -52,7 +53,6 @@ import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { PresEffect, PresEffectDirection } from './trails/PresEnums'; import SpringAnimation from './trails/SlideEffect'; import { SpringType, springMappings } from './trails/SpringUtils'; -import { TagsView } from '../TagsView'; export interface DocumentViewProps extends FieldViewSharedProps { hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected @@ -426,7 +426,7 @@ export class DocumentViewInternal extends DocComponent { this.Document.ignoreClick = false; - this.Document.onClick = this.Document[DocData].onClick = undefined; + this.Document.onClick = this.Document.$onClick = undefined; }, 'default on click'); deleteClicked = undoable(() => this._props.removeDocument?.(this.Document), 'delete doc'); @@ -758,7 +758,7 @@ export class DocumentViewInternal extends DocComponent ')[1]; const matchedTags = Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, tag, false, ['tags']).keys()); - const collectionDocs = DocListCast(collection[DocData].data).concat(collection); + const collectionDocs = DocListCast(collection.$data).concat(collection); let wid = 100; let created = false; const matchedDocs = matchedTags @@ -1749,6 +1749,6 @@ ScriptingGlobals.add(function updateTagsCollection(collection: Doc) { return aset; }, new Set()); - created && (collection[DocData].data = new List(Array.from(matchedDocs))); + created && (collection.$data = new List(Array.from(matchedDocs))); return true; }); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5b06e9fc5..5d9718760 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -284,10 +284,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { crop = (region: Doc | undefined, addCrop?: boolean) => { if (!region) return undefined; const cropping = Doc.MakeCopy(region, true); - const regionData = region[DocData]; - regionData.lockedPosition = true; - regionData.title = 'region:' + this.Document.title; - regionData.followLinkToggle = true; + region.$lockedPosition = true; + region.$title = 'region:' + this.Document.title; + region.$followLinkToggle = true; this.addDocument(region); const anchx = NumCast(cropping.x); const anchy = NumCast(cropping.y); @@ -300,24 +299,23 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { cropping._width = anchw * (this._props.NativeDimScaling?.() || 1); cropping._height = anchh * (this._props.NativeDimScaling?.() || 1); cropping.onClick = undefined; - const croppingProto = cropping[DocData]; - croppingProto.annotationOn = undefined; - croppingProto.isDataDoc = true; - croppingProto.backgroundColor = undefined; - croppingProto.proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO - croppingProto.type = DocumentType.IMG; - croppingProto.layout = ImageBox.LayoutString('data'); - croppingProto.data = ObjectField.MakeCopy(this.dataDoc[this.fieldKey] as ObjectField); - croppingProto.data_nativeWidth = anchw; - croppingProto.data_nativeHeight = anchh; - croppingProto.freeform_scale = viewScale; - croppingProto.freeform_panX = anchx / viewScale; - croppingProto.freeform_panY = anchy / viewScale; - croppingProto.freeform_scale_min = viewScale; - croppingProto.freeform_panX_min = anchx / viewScale; - croppingProto.freeform_panX_max = anchw / viewScale; - croppingProto.freeform_panY_min = anchy / viewScale; - croppingProto.freeform_panY_max = anchh / viewScale; + cropping.$annotationOn = undefined; + cropping.$isDataDoc = true; + cropping.$backgroundColor = undefined; + cropping.$proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO + cropping.$type = DocumentType.IMG; + cropping.$layout = ImageBox.LayoutString('data'); + cropping.$data = ObjectField.MakeCopy(this.dataDoc[this.fieldKey] as ObjectField); + cropping.$data_nativeWidth = anchw; + cropping.$data_nativeHeight = anchh; + cropping.$freeform_scale = viewScale; + cropping.$reeform_panX = anchx / viewScale; + cropping.$freeform_panY = anchy / viewScale; + cropping.$freeform_scale_min = viewScale; + cropping.$freeform_panX_min = anchx / viewScale; + cropping.$freeform_panX_max = anchw / viewScale; + cropping.$freeform_panY_min = anchy / viewScale; + cropping.$freeform_panY_max = anchh / viewScale; if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); cropping.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 9795febbe..32c9efbd9 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -105,7 +105,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { if (setResult) setResult?.(value); else target[key] = field; }; - const res = script.run({ this: Doc.Layout(doc), _setCacheResult_ }, console.log); + const res = script.run({ this: doc, _setCacheResult_ }, console.log); if (!res.success) { if (key) target[key] = script.originalScript; return false; diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index d5dc256d9..8bf65b637 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -252,7 +252,7 @@ export class LinkBox extends ViewBoxBaseComponent() { fontSize={fontSize} GetValue={() => linkDesc} SetValue={action(val => { - this.Document[DocData].link_description = val; + this.Document.$link_description = val; return true; })} /> @@ -262,8 +262,8 @@ export class LinkBox extends ViewBoxBaseComponent() { background={color} color={fontColor || lightOrDark(DashColor(color).fade(0.5).toString())} type={Type.PRIM} - val={StrCast(this.Document[DocData].link_description)} - setVal={action(val => (this.Document[DocData].link_description = val))} + val={StrCast(this.Document.$link_description)} + setVal={action(val => (this.Document.$link_description = val))} fillWidth /> */}
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index ff95f8547..6bec9c53d 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -1,7 +1,6 @@ import { action, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { DocData } from '../../../fields/DocSymbols'; import { StrCast } from '../../../fields/Types'; import { LinkManager } from '../../util/LinkManager'; import './LinkDescriptionPopup.scss'; @@ -48,7 +47,7 @@ export class LinkDescriptionPopup extends React.Component<{}> { onDismiss = (add: boolean) => { this.display = false; if (add) { - LinkManager.Instance.currentLink && (LinkManager.Instance.currentLink[DocData].link_description = this.description); + LinkManager.Instance.currentLink && (LinkManager.Instance.currentLink.$link_description = this.description); } this.description = ''; }; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 06b75e243..1f72206fc 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -129,15 +129,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { cropping._width = anchw; cropping._height = anchh; cropping.onClick = undefined; - const croppingProto = cropping[DocData]; - croppingProto.annotationOn = undefined; - croppingProto.isDataDoc = true; - croppingProto.proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO - croppingProto.type = DocumentType.IMG; - croppingProto.layout = ImageBox.LayoutString('data'); - croppingProto.data = new ImageField(ClientUtils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')); - croppingProto.data_nativeWidth = anchw; - croppingProto.data_nativeHeight = anchh; + cropping.$annotationOn = undefined; + cropping.$isDataDoc = true; + cropping.$proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO + cropping.$type = DocumentType.IMG; + cropping.$layout = ImageBox.LayoutString('data'); + cropping.$data = new ImageField(ClientUtils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')); + cropping.$data_nativeWidth = anchw; + cropping.$data_nativeHeight = anchh; if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); } diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 7ba313e92..53783e8a3 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -3,7 +3,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast } from '../../../../fields/Doc'; -import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { BoolCast, DocCast } from '../../../../fields/Types'; @@ -99,7 +98,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { }); screengrabber.overlayX = 70; // was -400 screengrabber.overlayY = 590; // was 0 - screengrabber[DocData][Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; + screengrabber['$' + Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; Doc.AddToMyOverlay(screengrabber); // just adds doc to overlay DocumentView.addViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 9adee53e8..fa099178c 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -331,7 +331,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { Doc.SetNativeHeight(imageSnapshot[DocData], Doc.NativeHeight(this.layoutDoc)); this._props.addDocument?.(imageSnapshot); DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { link_relationship: 'video snapshot' }); - // link && (DocCast(link.link_anchor_2)[DocData].timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3); // do we need to set an end time? should default to +0.1 + // link && (DocCast(link.link_anchor_2).$timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3); // do we need to set an end time? should default to +0.1 setTimeout(() => downX !== undefined && downY !== undefined && DocumentView.getFirstDocumentView(imageSnapshot)?.startDragging(downX, downY, dropActionType.move, true)); }; @@ -918,11 +918,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { crop = (region: Doc | undefined, addCrop?: boolean) => { if (!region) return undefined; const cropping = Doc.MakeCopy(region, true); - const regionData = region[DocData]; - regionData.backgroundColor = 'transparent'; - regionData.lockedPosition = true; - regionData.title = 'region:' + this.Document.title; - regionData.followLinkToggle = true; + region.$backgroundColor = 'transparent'; + region.$lockedPosition = true; + region.$title = 'region:' + this.Document.title; + region.$followLinkToggle = true; region._timecodeToHide = NumCast(region._timecodeToShow) + 0.0001; this.addDocument(region); const anchx = NumCast(cropping.x); @@ -938,25 +937,24 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { cropping.timecodeToHide = undefined; cropping.timecodeToShow = undefined; cropping.onClick = undefined; - const croppingProto = cropping[DocData]; - croppingProto.annotationOn = undefined; - croppingProto.isDataDoc = true; - croppingProto.proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO - croppingProto.type = DocumentType.VID; - croppingProto.layout = VideoBox.LayoutString('data'); - croppingProto.data = ObjectField.MakeCopy(this.dataDoc[this.fieldKey] as ObjectField); - croppingProto.data_nativeWidth = anchw; - croppingProto.data_nativeHeight = anchh; - croppingProto.videoCrop = true; - croppingProto.layout_currentTimecode = this.layoutDoc._layout_currentTimecode; - croppingProto.freeform_scale = viewScale; - croppingProto.freeform_scale_min = viewScale; - croppingProto.freeform_ = anchx / viewScale; - croppingProto.freeform_panY = anchy / viewScale; - croppingProto.freeform_panX_min = anchx / viewScale; - croppingProto.freeform_panX_max = anchw / viewScale; - croppingProto.freeform_panY_min = anchy / viewScale; - croppingProto.freeform_panY_max = anchh / viewScale; + cropping.$annotationOn = undefined; + cropping.$isDataDoc = true; + cropping.$proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO + cropping.$type = DocumentType.VID; + cropping.$layout = VideoBox.LayoutString('data'); + cropping.$data = ObjectField.MakeCopy(this.dataDoc[this.fieldKey] as ObjectField); + cropping.$data_nativeWidth = anchw; + cropping.$data_nativeHeight = anchh; + cropping.$videoCrop = true; + cropping.$layout_currentTimecode = this.layoutDoc._layout_currentTimecode; + cropping.$freeform_scale = viewScale; + cropping.$freeform_scale_min = viewScale; + cropping.$freeform_ = anchx / viewScale; + cropping.$freeform_panY = anchy / viewScale; + cropping.$freeform_panX_min = anchx / viewScale; + cropping.$freeform_panX_max = anchw / viewScale; + cropping.$freeform_panY_min = anchy / viewScale; + cropping.$freeform_panY_max = anchh / viewScale; if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); } diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx index 1cbfd5fba..e3408696b 100644 --- a/src/client/views/nodes/calendarBox/CalendarBox.tsx +++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx @@ -113,7 +113,7 @@ export class CalendarBox extends CollectionSubView() { if (!super.onInternalDrop(e, de)) return false; de.complete.docDragData?.droppedDocuments.forEach(doc => { const today = new Date().toISOString(); - if (!doc.date_range) doc[DocData].date_range = `${today}|${today}`; + if (!doc.date_range) doc.$date_range = `${today}|${today}`; }); return true; }; diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 6e9307d37..b023b1de6 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -733,9 +733,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { const x2 = parseFloat(values[2]) * Doc.NativeWidth(doc); const y2 = parseFloat(values[3]) * Doc.NativeHeight(doc) + foundChunk.startPage * Doc.NativeHeight(doc); - const annotationKey = Doc.LayoutFieldKey(doc) + '_annotations'; + const annotationKey = '$' + Doc.LayoutFieldKey(doc) + '_annotations'; - const existingDoc = DocListCast(doc[DocData][annotationKey]).find(d => d.citation_id === citation.citation_id); + const existingDoc = DocListCast(doc[annotationKey]).find(d => d.citation_id === citation.citation_id); const highlightDoc = existingDoc ?? this.createImageCitationHighlight(x1, y1, x2, y2, citation, annotationKey, doc); DocumentManager.Instance.showDocument(highlightDoc, { willZoomCentered: true }, () => {}); @@ -779,7 +779,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { _height: y2 - y1, backgroundColor: 'rgba(255, 255, 0, 0.5)', }); - highlight_doc[DocData].citation_id = citation.citation_id; + highlight_doc.$citation_id = citation.citation_id; Doc.AddDocToList(pdfDoc[DocData], annotationKey, highlight_doc); highlight_doc.annotationOn = pdfDoc; Doc.SetContainer(highlight_doc, pdfDoc); diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index e0450b202..827db190a 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -6,7 +6,6 @@ import { EditorView } from 'prosemirror-view'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; -import { DocData } from '../../../../fields/DocSymbols'; import { StrCast } from '../../../../fields/Types'; import './DashFieldView.scss'; import EquationEditor from './EquationEditor'; @@ -63,9 +62,9 @@ export class EquationViewInternal extends React.Component }}> { - this._textBoxDoc[DocData][this._fieldKey] = str; + this._textBoxDoc['$' + this._fieldKey] = str; }} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" diff --git a/src/client/views/nodes/imageEditor/ImageEditor.tsx b/src/client/views/nodes/imageEditor/ImageEditor.tsx index 657e689bb..85bd95d15 100644 --- a/src/client/views/nodes/imageEditor/ImageEditor.tsx +++ b/src/client/views/nodes/imageEditor/ImageEditor.tsx @@ -24,8 +24,8 @@ import { PointerHandler } from './imageEditorUtils/PointerHandler'; import { activeColor, bgColor, brushWidthOffset, canvasSize, eraserColor, freeformRenderSize, newCollectionSize, offsetDistanceY, offsetX } from './imageEditorUtils/imageEditorConstants'; import { CutMode, CursorData, ImageDimensions, ImageEditTool, ImageToolType, Point } from './imageEditorUtils/imageEditorInterfaces'; import { DocumentView } from '../DocumentView'; -import { DocData } from '../../../../fields/DocSymbols'; import { SettingsManager } from '../../../util/SettingsManager'; +import { Upload } from '../../../../server/SharedMediaTypes'; interface GenerativeFillProps { imageEditorOpen: boolean; @@ -397,9 +397,8 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc const newImgDoc = await createNewImgDoc(finalImg, firstDoc); if (newImgDoc) { // set the image to transparent to remove the background / brushstrokes - const docData = newImgDoc[DocData]; - docData.backgroundColor = 'transparent'; - docData.disableMixBlend = true; + newImgDoc.$backgroundColor = 'transparent'; + newImgDoc.$disableMixBlend = true; if (firstDoc) setIsFirstDoc(false); setEdits([...prevEdits, { url: finalImgURL, saveRes: undefined }]); } @@ -476,7 +475,7 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc const createNewImgDoc = async (img: HTMLImageElement, firstDoc: boolean /*, parent?: Doc */): Promise => { if (!imageRootDoc) return undefined; const { src } = img; - const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [src] }); + const [result] = (await Networking.PostToServer('/uploadRemoteImage', { sources: [src] })) as Upload.ImageInformation[]; const source = ClientUtils.prepend(result.accessPaths.agnostic.client); if (firstDoc) { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index ec97e067a..23155ebf3 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -532,11 +532,10 @@ export class PresBox extends ViewBoxBaseComponent() { const setData = bestTargetView?.ComponentView?.setData; if (setData) setData(activeItem.config_data); else { - const bestTargetData = bestTarget[DocData]; - const current = bestTargetData[fkey]; - const hash = bestTargetData[fkey] ? stringHash(Field.toString(bestTargetData[fkey] as FieldType)) : undefined; - if (hash) bestTargetData[fkey + '_' + hash] = current instanceof ObjectField ? current[Copy]() : current; - bestTargetData[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data; + const current = bestTarget['$' + fkey]; + const hash = bestTarget['$' + fkey] ? stringHash(Field.toString(bestTarget['$' + fkey] as FieldType)) : undefined; + if (hash) bestTarget['$' + fkey + '_' + hash] = current instanceof ObjectField ? current[Copy]() : current; + bestTarget['$' + fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data; } bestTarget[fkey + '_usePath'] = activeItem.config_usePath; setTimeout(() => { diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx index 1cceabed3..2283ef965 100644 --- a/src/client/views/smartdraw/SmartDrawHandler.tsx +++ b/src/client/views/smartdraw/SmartDrawHandler.tsx @@ -10,9 +10,11 @@ import { INode, parse } from 'svgson'; import { imageUrlToBase64, setupMoveUpEvents } from '../../../ClientUtils'; import { unimplementedFunction } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { InkData, InkField, InkTool } from '../../../fields/InkField'; +import { List } from '../../../fields/List'; import { BoolCast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; +import { PointData } from '../../../pen-gestures/GestureTypes'; +import { Upload } from '../../../server/SharedMediaTypes'; import { Networking } from '../../Network'; import { GPTCallType, gptAPICall, gptDrawingColor } from '../../apis/gpt/GPT'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -26,9 +28,6 @@ import { MarqueeView } from '../collections/collectionFreeForm'; import { ActiveInkArrowEnd, ActiveInkArrowStart, ActiveInkBezierApprox, ActiveInkColor, ActiveInkDash, ActiveInkFillColor, ActiveInkWidth, ActiveIsInkMask, DocumentView } from '../nodes/DocumentView'; import { FireflyDimensionsMap, FireflyImageData, FireflyImageDimensions } from './FireflyConstants'; import './SmartDrawHandler.scss'; -import { Upload } from '../../../server/SharedMediaTypes'; -import { PointData } from '../../../pen-gestures/GestureTypes'; -import { List } from '../../../fields/List'; export interface DrawingOptions { text?: string; @@ -153,9 +152,9 @@ export class SmartDrawHandler extends ObservableReactComponent { this._display = false; this.ShowRegenerate = true; this._showEditBox = false; - const docData = this._selectedDocs[0][DocData]; - this._lastResponse = StrCast(docData.drawingData); - this._lastInput = { text: StrCast(docData.ai_drawing_input), complexity: NumCast(docData.ai_drawing_complexity), size: NumCast(docData.ai_drawing_size), autoColor: BoolCast(docData.ai_drawing_colored), x: this._pageX, y: this._pageY }; + const docData = this._selectedDocs[0]; + this._lastResponse = StrCast(docData.$drawingData); + this._lastInput = { text: StrCast(docData.$ai_drawing_input), complexity: NumCast(docData.$ai_drawing_complexity), size: NumCast(docData.$ai_drawing_size), autoColor: BoolCast(docData.$ai_drawing_colored), x: this._pageX, y: this._pageY }; }; /** @@ -404,7 +403,7 @@ export class SmartDrawHandler extends ObservableReactComponent { const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`; try { const hrefBase64 = await imageUrlToBase64(hrefComplete); - const strokes = DocListCast(drawing[DocData].data); + const strokes = DocListCast(drawing.$data); const coords: string[] = []; strokes.forEach((stroke, i) => { const inkingStroke = DocumentView.getDocumentView(stroke)?.ComponentView as InkingStroke; @@ -423,14 +422,14 @@ export class SmartDrawHandler extends ObservableReactComponent { */ colorStrokes = undoable((res: string, drawing: Doc) => { const colorList = res.match(/\{.*?\}/g); - const strokes = DocListCast(drawing[DocData].data); + const strokes = DocListCast(drawing.$data); colorList?.forEach((colors, index) => { const strokeAndFill = colors.match(/#[0-9A-Fa-f]{6}/g); if (strokeAndFill && strokeAndFill.length == 2) { - strokes[index][DocData].color = strokeAndFill[0]; + strokes[index].$color = strokeAndFill[0]; const inkStroke = DocumentView.getDocumentView(strokes[index])?.ComponentView as InkingStroke; const { inkData } = inkStroke.inkScaledData(); - InkingStroke.IsClosed(inkData) ? (strokes[index][DocData].fillColor = strokeAndFill[1]) : (strokes[index][DocData].fillColor = undefined); + InkingStroke.IsClosed(inkData) ? (strokes[index].$fillColor = strokeAndFill[1]) : (strokes[index].$fillColor = undefined); } }); }, 'color strokes'); diff --git a/src/client/views/smartdraw/StickerPalette.tsx b/src/client/views/smartdraw/StickerPalette.tsx index e3305851a..080a05d42 100644 --- a/src/client/views/smartdraw/StickerPalette.tsx +++ b/src/client/views/smartdraw/StickerPalette.tsx @@ -9,7 +9,6 @@ import ReactLoading from 'react-loading'; import { returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils'; import { emptyFunction, numberRange } from '../../../Utils'; import { Doc, DocListCast, returnEmptyDoclist } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { ImageCast, NumCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -133,7 +132,7 @@ export class StickerPalette extends ObservableReactComponent { this._isLoading = true; - const prevDrawings = DocListCast(this._props.Document[DocData].data); - this._props.Document[DocData].data = undefined; + const prevDrawings = DocListCast(this._props.Document.$data); + this._props.Document.$data = undefined; SmartDrawHandler.Instance.AddDrawing = this.addDrawing; this._canInteract = false; Promise.all( @@ -164,7 +163,7 @@ export class StickerPalette extends ObservableReactComponent { this._gptRes.push(gptRes); - drawing[DocData].freeform_fitContentsToBox = true; + drawing.$freeform_fitContentsToBox = true; Doc.AddDocToList(this._props.Document, 'data', drawing); }; @@ -176,17 +175,16 @@ export class StickerPalette extends ObservableReactComponent { const cIndex = NumCast(this._props.Document.carousel_index); const focusedDrawing = DocListCast(this._props.Document.data)[cIndex]; - const docData = focusedDrawing[DocData]; - docData.title = this._opts.text?.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text; - docData.ai_drawing_input = this._opts.text; - docData.ai_drawing_complexity = this._opts.complexity; - docData.ai_drawing_colored = this._opts.autoColor; - docData.ai_drawing_size = this._opts.size; - docData.ai_drawing_data = this._gptRes[cIndex]; - docData.ai = 'gpt'; + focusedDrawing.$title = this._opts.text?.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text; + focusedDrawing.$ai_drawing_input = this._opts.text; + focusedDrawing.$ai_drawing_complexity = this._opts.complexity; + focusedDrawing.$ai_drawing_colored = this._opts.autoColor; + focusedDrawing.$ai_drawing_size = this._opts.size; + focusedDrawing.$ai_drawing_data = this._gptRes[cIndex]; + focusedDrawing.$ai = 'gpt'; focusedDrawing.width = this._opts.size; - docData.x = this._opts.x; - docData.y = this._opts.y; + focusedDrawing.x = this._opts.x; + focusedDrawing.y = this._opts.y; StickerPalette.addToPalette(focusedDrawing).then(() => this.resetPalette(true)); }; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index e2f708700..4bf04da5c 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -273,12 +273,12 @@ export class Doc extends RefField { public static AddToMyOverlay(doc: Doc) { return Doc.ActiveDashboard ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore public static RemFromMyOverlay(doc: Doc) { return Doc.ActiveDashboard ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore public static AddToMyPublished(doc: Doc) { - doc[DocData].title_custom = true; - doc[DocData].layout_showTitle = 'title'; + doc.$title_custom = true; + doc.$layout_showTitle = 'title'; Doc.ActiveDashboard ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore public static RemFromMyPublished(doc: Doc){ - doc[DocData].title_custom = false; - doc[DocData].layout_showTitle = undefined; + doc.$title_custom = false; + doc.$layout_showTitle = undefined; Doc.ActiveDashboard ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore public static IsComicStyle(doc?: Doc) { return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic' ; } // prettier-ignore @@ -629,7 +629,7 @@ export namespace Doc { */ export function RemoveDocFromList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, ignoreProto = false) { const key = fieldKey || Doc.LayoutFieldKey(listDoc); - const list = Doc.Get(listDoc, key, ignoreProto) === undefined ? (listDoc[DocData][key] = new List()) : Cast(listDoc[key], listSpec(Doc)); + const list = Doc.Get(listDoc, key, ignoreProto) === undefined ? (listDoc['$' + key] = new List()) : Cast(listDoc[key], listSpec(Doc)); if (list) { const ind = list.indexOf(doc); if (ind !== -1) { @@ -646,7 +646,7 @@ export namespace Doc { */ export function AddDocToList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean, ignoreProto?: boolean) { const key = fieldKey || Doc.LayoutFieldKey(listDoc); - const list = Doc.Get(listDoc, key, ignoreProto) === undefined ? (listDoc[DocData][key] = new List()) : Cast(listDoc[key], listSpec(Doc)); + const list = Doc.Get(listDoc, key, ignoreProto) === undefined ? (listDoc['$' + key] = new List()) : Cast(listDoc[key], listSpec(Doc)); if (list) { if (!allowDuplicates) { const pind = list.findIndex(d => d instanceof Doc && d[Id] === doc[Id]); @@ -691,7 +691,7 @@ export namespace Doc { Doc.SetLayout(embedding, Doc.MakeEmbedding(layout)); } embedding.createdFrom = doc; - embedding.proto_embeddingId = doc[DocData].proto_embeddingId = Doc.GetEmbeddings(doc).length - 1; + embedding.proto_embeddingId = doc.$proto_embeddingId = Doc.GetEmbeddings(doc).length - 1; !Doc.GetT(embedding, 'title', 'string', true) && (embedding.title = ComputedField.MakeFunction(`renameEmbedding(this)`)); embedding.author = ClientUtils.CurrentUserEmail(); @@ -699,9 +699,8 @@ export namespace Doc { } export function BestEmbedding(doc: Doc) { - const dataDoc = doc[DocData]; - const availableEmbeddings = Doc.GetEmbeddings(dataDoc); - const bestEmbedding = [...(dataDoc !== doc ? [doc] : []), ...availableEmbeddings].find(d => !d.embedContainer && d.author === ClientUtils.CurrentUserEmail()); + const availableEmbeddings = Doc.GetEmbeddings(doc); + const bestEmbedding = [...(doc[DocData] !== doc ? [doc] : []), ...availableEmbeddings].find(d => !d.embedContainer && d.author === ClientUtils.CurrentUserEmail()); bestEmbedding && Doc.AddEmbedding(doc, doc); return bestEmbedding ?? Doc.MakeEmbedding(doc); } @@ -1475,7 +1474,7 @@ export namespace Doc { * @returns */ export function getDescription(doc: Doc) { - const curDescription = StrCast(doc[DocData][Doc.LayoutFieldKey(doc) + '_description']); + const curDescription = StrCast(doc['$' + Doc.LayoutFieldKey(doc) + '_description']); const docText = (async (tdoc:Doc) => { switch (tdoc.type) { case DocumentType.PDF: return curDescription || StrCast(tdoc.text).split(/\s+/).slice(0, 50).join(' '); // first 50 words of pdf text @@ -1484,7 +1483,7 @@ export namespace Doc { case DocumentType.RTF: return RTFCast(tdoc[Doc.LayoutFieldKey(tdoc)]).Text; default: return StrCast(tdoc.title).startsWith("Untitled") ? "" : StrCast(tdoc.title); }}); // prettier-ignore - return docText(doc).then(text => (doc[DocData][Doc.LayoutFieldKey(doc) + '_description'] = text)); + return docText(doc).then(text => (doc['$' + Doc.LayoutFieldKey(doc) + '_description'] = text)); } // prettier-ignore @@ -1737,7 +1736,7 @@ ScriptingGlobals.add(function idToDoc(id: string): Doc { }); // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function renameEmbedding(doc: Doc) { - return StrCast(doc[DocData].title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`; + return StrCast(doc.$title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`; }); // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function getProto(doc: Doc) { diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts index b294ee8c6..6e2d7eb78 100644 --- a/src/fields/ScriptField.ts +++ b/src/fields/ScriptField.ts @@ -210,6 +210,7 @@ export class ComputedField extends ScriptField { this._lastComputedResult = this._cachedResult ?? computedFn(() => + ((val) => val instanceof Array ? new List(val) : val)( this.script.compiled && this.script.run( { @@ -220,7 +221,7 @@ export class ComputedField extends ScriptField { _readOnly_: true, }, console.log - ).result as FieldResult + ).result as FieldResult) )(); // prettier-ignore return this._lastComputedResult; }; -- cgit v1.2.3-70-g09d2 From 705975eb43e7904c62e7e847478f6d0dac60d443 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 23 Mar 2025 18:14:31 -0400 Subject: more _props.Document to .Document refactoring. type updates to prosemirrortransfer --- src/client/util/SharingManager.tsx | 2 +- src/client/views/DocComponent.tsx | 85 +++++++--- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/FieldsDropdown.tsx | 4 +- src/client/views/FilterPanel.tsx | 4 +- src/client/views/LightboxView.tsx | 2 +- src/client/views/SidebarAnnos.tsx | 24 +-- src/client/views/TemplateMenu.tsx | 1 - src/client/views/animationtimeline/Timeline.tsx | 56 +++---- .../collections/CollectionMasonryViewFieldRow.tsx | 8 +- .../views/collections/CollectionNoteTakingView.tsx | 15 +- .../collections/CollectionNoteTakingViewColumn.tsx | 18 +-- .../views/collections/CollectionPivotView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 19 +-- .../CollectionStackingViewFieldColumn.tsx | 28 ++-- src/client/views/collections/CollectionSubView.tsx | 10 +- .../views/collections/CollectionTimeView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/TabDocView.tsx | 28 ++-- .../CollectionFreeFormInfoUI.tsx | 14 +- .../CollectionFreeFormPannableContents.tsx | 4 +- .../CollectionFreeFormRemoteCursors.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 48 +++--- .../collections/collectionFreeForm/MarqueeView.tsx | 1 + .../collectionSchema/SchemaCellField.tsx | 4 +- .../collections/collectionSchema/SchemaRowBox.tsx | 2 +- .../collectionSchema/SchemaTableCell.tsx | 46 +++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 30 ++-- .../nodes/DataVizBox/components/Histogram.tsx | 13 +- .../nodes/DataVizBox/components/LineChart.tsx | 8 +- .../views/nodes/DataVizBox/components/PieChart.tsx | 16 +- .../views/nodes/DataVizBox/components/TableBox.tsx | 10 +- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/FieldView.tsx | 4 +- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 10 +- src/client/views/nodes/MapBox/MapBox.tsx | 2 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 3 +- src/client/views/nodes/PDFBox.tsx | 3 +- src/client/views/nodes/ScreenshotBox.tsx | 2 - src/client/views/nodes/WebBox.tsx | 2 +- .../views/nodes/formattedText/DashFieldView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 10 +- .../formattedText/ProsemirrorExampleTransfer.ts | 174 +++++++++++---------- .../views/nodes/formattedText/SummaryView.tsx | 46 +++--- src/client/views/pdf/PDFViewer.tsx | 30 ++-- src/client/views/search/SearchBox.tsx | 16 +- src/client/views/smartdraw/StickerPalette.tsx | 16 +- src/fields/RichTextUtils.ts | 3 +- src/fields/Types.ts | 5 - src/server/DashSession/DashSessionAgent.ts | 4 +- 52 files changed, 438 insertions(+), 414 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 3a248400b..962f51cd4 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -633,7 +633,7 @@ export class SharingManager extends React.Component { private focusOn = (contents: string) => { const title = this.targetDoc ? StrCast(this.targetDoc.title) : ''; - const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.props.Document) : [this.targetDoc]; + const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.Document) : [this.targetDoc]; return ( () { } /** - * This is the document being rendered. In the case of a compound template, it - * may not be the actual document rendered and it also may not be the 'real' root document. - * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) + * This is the doc that is being rendered. It will be either: + * 1) the same as Document if the root of a regular or compound Doc is rendered + * 2) the same as the layoutDoc if a component of a compound Doc is rendered. + * NOTE: it is very unlikely that you really want to use this method. Instead + * consider: Document, layoutDoc, dataDoc */ - get Document() { - return DocCast(this._props.Document.rootDocument, this._props.Document); + get _renderDoc() { + return this._props.Document; } /** - * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. + * This is the "root" Doc being rendered. In the case of a compound template Doc, + * this is the outermost Doc that represents the entire compound Doc. It is not + * necessarily the Doc being rendered in the current React component. + * This Doc inherits from the dataDoc, and may or may not inherit (or be) the layoutDoc. + */ + get Document() { + return DocCast(this._renderDoc.rootDocument, this._renderDoc); + } + /** + * This is the document being rendered by the React component. In the + * case of a compound template, this will be the expanded template Doc + * that represents the component of the compound Doc being rendered. + * This may or may not inherit from the data doc. */ @computed get layoutDoc() { - return this._props.LayoutTemplateString ? this._props.Document : Doc.Layout(this._props.Document, this._props.LayoutTemplate?.()); + return this._props.LayoutTemplateString ? this._renderDoc : Doc.Layout(this._renderDoc, this._props.LayoutTemplate?.()); } /** - * This is the unique data repository for a dcoument that stores the intrinsic document data + * This is the unique data repository for a document that stores the intrinsic document data. */ @computed get dataDoc() { - return this._props.Document[DocData]; + return this._renderDoc[DocData]; } } return Component; @@ -75,25 +89,40 @@ export function ViewBoxBaseComponent

() { } /** - * This is the document being rendered. In the case of a compound template, it - * may not be the actual document rendered and it also may not be the 'real' root document. - * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) + * This is the doc that is being rendered. It will be either: + * 1) the same as Document if the root of a regular or compound Doc is rendered + * 2) the same as the layoutDoc if a component of a compound Doc is rendered. + * NOTE: it is very unlikely that you really want to use this method. Instead + * consider: Document, layoutDoc, dataDoc + */ + get _renderDoc() { + return this._props.Document; + } + + /** + * This is the "root" Doc being rendered. In the case of a compound template Doc, + * this is the outermost Doc that represents the entire compound Doc. It is not + * necessarily the Doc being rendered in the current React component. + * This Doc inherits from the dataDoc, and may or may not inherit (or be) the layoutDoc. */ get Document() { - return DocCast(this._props.Document.rootDocument, this._props.Document); + return DocCast(this._renderDoc.rootDocument, this._renderDoc); } /** - * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. + * This is the document being rendered by the React component. In the + * case of a compound template, this will be the expanded template Doc + * that represents the component of the compound Doc being rendered. + * This may or may not inherit from the data doc. */ @computed get layoutDoc() { - return Doc.Layout(this._props.Document); + return Doc.Layout(this._renderDoc); } /** * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this._props.Document.isTemplateForField || this._props.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._props.Document[DocData]) : this._props.Document[DocData]; + return this._renderDoc.isTemplateForField || this._renderDoc.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._renderDoc[DocData]) : this._renderDoc[DocData]; } /** @@ -133,25 +162,37 @@ export function ViewBoxAnnotatableComponent

() { } /** - * This is the document being rendered. In the case of a compound template, it - * may not be the actual document rendered and it also may not be the 'real' root document. - * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) + * This is the doc that is being rendered. It will be either: + * 1) the same as Document if the root of a regular or compound Doc is rendered + * 2) the same as the layoutDoc if a component of a compound Doc is rendered. + * NOTE: it would unlikely that you really want to use this instead of the + * other Doc options (Document, layoutDoc, dataDoc) + */ + get _renderDoc() { + return this._props.Document; + } + + /** + * This is the "root" Doc being rendered. In the case of a compound template Doc, + * this is the outermost Doc that represents the entire compound Doc. It is not + * necessarily the Doc being rendered in the current React component. + * This Doc inherits from the dataDoc, and may or may not inherit (or be) the layoutDoc. */ @computed get Document() { - return DocCast(this._props.Document.rootDocument, this._props.Document); + return DocCast(this._renderDoc.rootDocument, this._renderDoc); } /** * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. */ @computed get layoutDoc() { - return Doc.Layout(this._props.Document); + return Doc.Layout(this._renderDoc); } /** * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this._props.Document.isTemplateForField || this._props.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._props.Document[DocData]) : this._props.Document[DocData]; + return this._renderDoc.isTemplateForField || this._renderDoc.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._renderDoc[DocData]) : this._props.Document[DocData]; } /** diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 92b4d6fbf..19b987cb5 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -635,7 +635,7 @@ export class DocumentDecorations extends ObservableReactComponent void; menuClose?: () => void; placeholder?: string | (() => string); @@ -36,7 +36,7 @@ export class FieldsDropdown extends ObservableReactComponent(); - SearchUtil.foreachRecursiveDoc([this._props.Document], (depth, doc) => allDocs.add(doc)); + SearchUtil.foreachRecursiveDoc([this._props.Doc], (depth, doc) => allDocs.add(doc)); return Array.from(allDocs); } diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 4fc8d7a68..c3b3f9d0c 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -379,7 +379,7 @@ export class FilterPanel extends ObservableReactComponent {

- +
{/* THE FOLLOWING CODE SHOULD BE DEVELOPER FOR BOOLEAN EXPRESSION (AND / OR) */} {/*
@@ -443,7 +443,7 @@ export class FilterPanel extends ObservableReactComponent {
- +
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 5698da785..de2c7cd09 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -317,7 +317,7 @@ export class LightboxView extends ObservableReactComponent {
- {this._showPalette && (this._annoPaletteView = r)} Document={DocCast(Doc.UserDoc().myLightboxDrawings)} />} + {this._showPalette && (this._annoPaletteView = r)} Doc={DocCast(Doc.UserDoc().myLightboxDrawings)} />} {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length ? true : false, this.previous)} {this.renderNavBtn( this._props.PanelWidth - Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]), diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index b3f3a4478..3c0611f03 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -22,7 +22,7 @@ import { FieldViewProps } from './nodes/FieldView'; interface ExtraProps { fieldKey: string; - Document: Doc; + Doc: Doc; layoutDoc: Doc; dataDoc: Doc; // usePanelWidth: boolean; @@ -45,7 +45,7 @@ export class SidebarAnnos extends ObservableReactComponent(); @computed get allMetadata() { const keys = new Map>(); - DocListCast(this._props.Document[this.sidebarKey]).forEach(doc => + DocListCast(this._props.Doc[this.sidebarKey]).forEach(doc => SearchUtil.documentKeys(doc) .filter(key => key[0] && key[0] !== '_' && key[0] === key[0].toUpperCase()) .map(key => keys.set(key, doc[key])) @@ -54,7 +54,7 @@ export class SidebarAnnos extends ObservableReactComponent(); - DocListCast(this._props.Document[this.sidebarKey]).forEach(doc => StrListCast(doc.tags).forEach(tag => keys.add(tag))); + DocListCast(this._props.Doc[this.sidebarKey]).forEach(doc => StrListCast(doc.tags).forEach(tag => keys.add(tag))); return Array.from(keys.keys()) .filter(key => key[0]) .filter(key => !key.startsWith('_') && (key[0] === '#' || key[0] === key[0].toUpperCase())) @@ -62,7 +62,7 @@ export class SidebarAnnos extends ObservableReactComponent(); - DocListCast(this._props.Document[this.sidebarKey]).forEach(doc => keys.add(StrCast(doc.author))); + DocListCast(this._props.Doc[this.sidebarKey]).forEach(doc => keys.add(StrCast(doc.author))); return Array.from(keys.keys()).sort(); } @@ -72,7 +72,7 @@ export class SidebarAnnos extends ObservableReactComponent data.split(':')[0]) .filter(data => !filterExlusions?.includes(data.split(':')[0])) .map(data => { - const key = '$'+data.split(':')[0]; + const key = '$' + data.split(':')[0]; const val = Field.Copy(this.allMetadata.get(key)); target[key] = val; return { @@ -148,7 +148,7 @@ export class SidebarAnnos extends ObservableReactComponent { - if (DocListCast(this._props.Document[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { + if (DocListCast(this._props.Doc[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { if (this.childFilters()) { // if any child filters exist, get rid of them this._props.layoutDoc._childFilters = new List(); @@ -189,7 +189,7 @@ export class SidebarAnnos extends ObservableReactComponent { const active = this.childFilters().includes(`tags${Doc.FilterSep}${tag}${Doc.FilterSep}check`); return ( -
Doc.setDocFilter(this._props.Document, 'tags', tag, 'check', true, undefined, e.shiftKey)}> +
Doc.setDocFilter(this._props.Doc, 'tags', tag, 'check', true, undefined, e.shiftKey)}> {tag}
); @@ -197,7 +197,7 @@ export class SidebarAnnos extends ObservableReactComponent { const active = this.childFilters().includes(`${tag}${Doc.FilterSep}${Doc.FilterAny}${Doc.FilterSep}exists`); return ( -
Doc.setDocFilter(this._props.Document, tag, Doc.FilterAny, 'exists', true, undefined, e.shiftKey)}> +
Doc.setDocFilter(this._props.Doc, tag, Doc.FilterAny, 'exists', true, undefined, e.shiftKey)}> {tag}
); @@ -205,7 +205,7 @@ export class SidebarAnnos extends ObservableReactComponent { const active = this.childFilters().includes(`author:${user}:check`); return ( -
Doc.setDocFilter(this._props.Document, 'author', user, 'check', true, undefined, e.shiftKey)}> +
Doc.setDocFilter(this._props.Doc, 'author', user, 'check', true, undefined, e.shiftKey)}> {user}
); @@ -216,9 +216,9 @@ export class SidebarAnnos extends ObservableReactComponent diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 680c8ed0e..1266a11c1 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -80,7 +80,6 @@ export class TemplateMenu extends React.Component { const addedTypes = DocListCast(Cast(Doc.UserDoc().template_clickFuncs, Doc, null)?.data); const templateMenu: Array = []; templateMenu.push(); - // eslint-disable-next-line no-return-assign addedTypes.concat(noteTypes).map(template => (template.treeView_Checked = this.templateIsUsed(firstDoc, template))); this._addedKeys && Array.from(this._addedKeys) diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 15683ebf2..cd2c7df1b 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -46,7 +46,7 @@ import { Id } from '../../../fields/FieldSymbols'; */ @observer -export class Timeline extends ObservableReactComponent { +export class Timeline extends ObservableReactComponent { // readonly constants private readonly DEFAULT_TICK_SPACING: number = 50; private readonly MAX_TITLE_HEIGHT = 75; @@ -57,7 +57,7 @@ export class Timeline extends ObservableReactComponent { private DEFAULT_CONTAINER_HEIGHT: number = 330; private MIN_CONTAINER_HEIGHT: number = 205; - constructor(props: FieldViewProps) { + constructor(props: FieldViewProps & { Doc: Doc }) { super(props); makeObservable(this); } @@ -90,11 +90,11 @@ export class Timeline extends ObservableReactComponent { */ @computed private get children(): Doc[] { - const annotatedDoc = [DocumentType.IMG, DocumentType.VID, DocumentType.PDF, DocumentType.MAP].includes(StrCast(this._props.Document.type) as unknown as DocumentType); + const annotatedDoc = [DocumentType.IMG, DocumentType.VID, DocumentType.PDF, DocumentType.MAP].includes(StrCast(this._props.Doc.type) as unknown as DocumentType); if (annotatedDoc) { - return DocListCast(this._props.Document[Doc.LayoutFieldKey(this._props.Document) + '_annotations']); + return DocListCast(this._props.Doc[Doc.LayoutFieldKey(this._props.Doc) + '_annotations']); } - return DocListCast(this._props.Document[this._props.fieldKey]); + return DocListCast(this._props.Doc[this._props.fieldKey]); } /// //////lifecycle functions//////////// @@ -104,21 +104,21 @@ export class Timeline extends ObservableReactComponent { this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; // check if relHeight is less than Maxheight. Else, just set relheight to max this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; // offset this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; // twice the titleheight + offset - if (!this._props.Document.AnimationLength) { + if (!this._props.Doc.AnimationLength) { // if animation length did not exist - this._props.Document.AnimationLength = this._time; // set it to default time + this._props.Doc.AnimationLength = this._time; // set it to default time } else { - this._time = NumCast(this._props.Document.AnimationLength); // else, set time to animationlength stored from before + this._time = NumCast(this._props.Doc.AnimationLength); // else, set time to animationlength stored from before } this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); // the entire length of the timeline div (actual div part itself) this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see) this._visibleStart = this._infoContainer.current!.scrollLeft; // where the div starts - this._props.Document.isATOn = !this._props.Document.isATOn; // turns the boolean on, saying AT (animation timeline) is on + this._props.Doc.isATOn = !this._props.Doc.isATOn; // turns the boolean on, saying AT (animation timeline) is on this.toggleHandle(); } componentWillUnmount() { - this._props.Document.AnimationLength = this._time; // save animation length + this._props.Doc.AnimationLength = this._time; // save animation length } /// ////////////////////////////////////////////// @@ -224,7 +224,7 @@ export class Timeline extends ObservableReactComponent { */ @action onPanDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.onPanMove, emptyFunction, e => this.changeCurrentBarX(this._trackbox.current!.scrollLeft + e.clientX - this._trackbox.current!.getBoundingClientRect().left)); + setupMoveUpEvents(this, e, this.onPanMove, emptyFunction, movEv => this.changeCurrentBarX(this._trackbox.current!.scrollLeft + movEv.clientX - this._trackbox.current!.getBoundingClientRect().left)); }; /** @@ -241,7 +241,7 @@ export class Timeline extends ObservableReactComponent { this._visibleStart -= e.movementX; this._totalLength -= e.movementX; this._time -= RegionHelpers.convertPixelTime(e.movementX, 'mili', 'time', this._tickSpacing, this._tickIncrement); - this._props.Document.AnimationLength = this._time; + this._props.Doc.AnimationLength = this._time; } return false; }; @@ -259,8 +259,8 @@ export class Timeline extends ObservableReactComponent { setupMoveUpEvents( this, e, - action(e => { - const offset = e.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom; + action(movEv => { + const offset = movEv.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom; this._containerHeight = clamp(this.MIN_CONTAINER_HEIGHT, this._containerHeight + offset, this.MAX_CONTAINER_HEIGHT); return false; }), @@ -358,7 +358,7 @@ export class Timeline extends ObservableReactComponent { const size = 40 * scale; // 50 is default const iconSize = 25; const width: number = this._props.PanelWidth(); - const modeType = this._props.Document.isATOn ? 'Author' : 'Play'; + const modeType = this._props.Doc.isATOn ? 'Author' : 'Play'; // decides if information should be omitted because the timeline is very small // if its less than 950 pixels then it's going to be overlapping @@ -397,7 +397,7 @@ export class Timeline extends ObservableReactComponent { tickIncrement={this._tickIncrement} time={this._time} parent={this} - isAuthoring={BoolCast(this._props.Document.isATOn)} + isAuthoring={BoolCast(this._props.Doc.isATOn)} currentBarX={this._currentBarX} totalLength={this._totalLength} visibleLength={this._visibleLength} @@ -418,10 +418,10 @@ export class Timeline extends ObservableReactComponent {
{this.timeIndicator(lengthString, totalTime)} -
this.resetView(this._props.Document)}> +
this.resetView(this._props.Doc)}>
-
this.setView(this._props.Document)}> +
this.setView(this._props.Doc)}>
@@ -431,17 +431,17 @@ export class Timeline extends ObservableReactComponent { }; timeIndicator(lengthString: string, totalTime: number) { - if (this._props.Document.isATOn) { - return
{`Total: ${this.toReadTime(totalTime)}`}
; + if (this._props.Doc.isATOn) { + return
{`Total: ${this.toReadTime(totalTime)}`}
; } else { const ctime = `Current: ${this.getCurrentTime()}`; const ttime = `Total: ${this.toReadTime(this._time)}`; return (
-
+
{ctime}
-
+
{ttime}
@@ -467,8 +467,8 @@ export class Timeline extends ObservableReactComponent { const roundToggleContainer = this._roundToggleContainerRef.current!; const timelineContainer = this._timelineContainer.current!; - this._props.Document.isATOn = !this._props.Document.isATOn; - if (!BoolCast(this._props.Document.isATOn)) { + this._props.Doc.isATOn = !this._props.Doc.isATOn; + if (!BoolCast(this._props.Doc.isATOn)) { // turning on playmode... roundToggle.style.transform = 'translate(0px, 0px)'; roundToggle.style.animationName = 'turnoff'; @@ -543,7 +543,7 @@ export class Timeline extends ObservableReactComponent { // change visible and total width return (
-
+
{this.drawTicks()} @@ -551,7 +551,7 @@ export class Timeline extends ObservableReactComponent {
- {[...this.children, this._props.Document].map(doc => ( + {[...this.children, this._props.Doc].map(doc => ( this.mapOfTracks.push(ref)} @@ -563,7 +563,7 @@ export class Timeline extends ObservableReactComponent { time={this._time} tickSpacing={this._tickSpacing} tickIncrement={this._tickIncrement} - collection={this._props.Document} + collection={this._props.Doc} timelineVisible={true} /> ))} @@ -571,7 +571,7 @@ export class Timeline extends ObservableReactComponent {
Current: {this.getCurrentTime()}
- {[...this.children, this._props.Document].map(doc => ( + {[...this.children, this._props.Doc].map(doc => (
Doc.BrushDoc(doc)} onPointerOut={() => Doc.UnBrushDoc(doc)}>

{StrCast(doc.title)}

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 4fe73895e..89ccf5a0f 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -22,7 +22,7 @@ import './CollectionStackingView.scss'; interface CMVFieldRowProps { rows: () => number; headings: () => object[]; - Document: Doc; + Doc: Doc; chromeHidden?: boolean; heading: string; headingObject: SchemaHeaderField | undefined; @@ -73,7 +73,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent { this._dropDisposer?.(); - if (ele) this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this), this._props.Document); + if (ele) this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this), this._props.Doc); else if (this._ele) this.props.refList.splice(this.props.refList.indexOf(this._ele), 1); this._ele = ele; }; @@ -189,7 +189,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent { - const embedding = Doc.MakeEmbedding(this._props.Document); + const embedding = Doc.MakeEmbedding(this._props.Doc); const key = this._props.pivotField; let value = this.getValue(this.heading); value = typeof value === 'string' ? `"${value}"` : value; @@ -289,7 +289,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent evContents} SetValue={this.headingChanged} contents={evContents} oneLine />; - return this._props.Document.miniHeaders ? ( + return this._props.Doc.miniHeaders ? (
{editableHeaderView}
) : !this._props.headingObject ? null : (
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index 4650727eb..2dabd3269 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -32,6 +32,7 @@ import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { Property } from 'csstype'; +import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; /** * CollectionNoteTakingView is a column-based view for displaying documents. In this view, the user can (1) @@ -437,10 +438,10 @@ export class CollectionNoteTakingView extends CollectionSubView() { }; @undoBatch - onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => { - if ((e.ctrlKey || fieldProps.Document._createDocOnCR) && ['Enter'].includes(e.key)) { + onKeyDown = (e: React.KeyboardEvent, textBox: FormattedTextBox) => { + if ((e.ctrlKey || textBox.Document._createDocOnCR) && ['Enter'].includes(e.key)) { e.stopPropagation?.(); - const newDoc = Doc.MakeCopy(fieldProps.Document, true); + const newDoc = Doc.MakeCopy(textBox.Document, true); newDoc.$text = undefined; DocumentView.SetSelectOnLoad(newDoc); return this.addDocument?.(newDoc); @@ -543,8 +544,8 @@ export class CollectionNoteTakingView extends CollectionSubView() { addDocument={this.addDocument} chromeHidden={this.chromeHidden} colHeaderData={this.colHeaderData} - Document={this.Document} - TemplateDataDocument={this._props.TemplateDataDocument} + Doc={this.Document} + TemplateDataDoc={this._props.TemplateDataDocument} resizeColumns={this.resizeColumns} renderChildren={this.children} numGroupColumns={this.numGroupColumns} @@ -567,7 +568,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { @undoBatch remColumn = (value: SchemaHeaderField) => { - const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); + const colHdrData = Array.from(Cast(this.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); if (value) { const index = colHdrData.indexOf(value); index !== -1 && colHdrData.splice(index, 1); @@ -701,7 +702,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { {this.renderedSections}
{ this.layoutDoc._pivotField = fieldKey; this.removeEmptyColumns(); diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index df9b5a1eb..f283b0abe 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -21,8 +21,8 @@ import './CollectionNoteTakingView.scss'; import { DocumentView } from '../nodes/DocumentView'; interface CSVFieldColumnProps { - Document: Doc; - TemplateDataDocument: Opt; + Doc: Doc; + TemplateDataDoc: Opt; backgroundColor?: () => string | undefined; docList: Doc[]; heading: string; @@ -65,7 +65,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent hd.heading === this._props.headingObject?.heading && hd.color === this._props.headingObject.color); return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%'; @@ -81,7 +81,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { this.dropDisposer?.(); - if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document); + if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Doc); else if (this._ele) this.props.refList.slice(this.props.refList.indexOf(this._ele), 1); this._ele = ele; }; @@ -155,7 +155,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { - const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); + const colHdrData = Array.from(Cast(this._props.Doc[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); if (this._props.headingObject) { // this._props.docList.forEach(d => (d['$'+this._props.pivotField] = undefined)); colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1); @@ -184,11 +184,11 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { - Doc.GetProto(this._props.Document)[name] = ''; + Doc.GetProto(this._props.Doc)[name] = ''; const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true }); if (created) { - if (this._props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this._props.Document); + if (this._props.Doc.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Doc); } this._props.addDocument?.(created); } @@ -267,7 +267,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0, + marginLeft: this._props.headings().findIndex(h => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Doc.xMargin) : 0, }}>
{this.innards} diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx index 2600c0f57..4736070c3 100644 --- a/src/client/views/collections/CollectionPivotView.tsx +++ b/src/client/views/collections/CollectionPivotView.tsx @@ -103,7 +103,7 @@ export class CollectionPivotView extends CollectionSubView() { {this.contents}
{ this.layoutDoc._pivotField = fieldKey; }} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 9972fe03d..883b0bbe3 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -34,6 +34,7 @@ import './CollectionStackingView.scss'; import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { computedFn } from 'mobx-utils'; +import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; export type collectionStackingViewProps = { sortFunc?: (a: Doc, b: Doc) => number; @@ -309,15 +310,15 @@ export class CollectionStackingView extends CollectionSubView { + onKeyDown = (e: React.KeyboardEvent, textBox: FormattedTextBox) => { if (['Enter'].includes(e.key) && e.ctrlKey) { e.stopPropagation?.(); - const layoutFieldKey = StrCast(fieldProps.fieldKey); - const newDoc = Doc.MakeCopy(fieldProps.Document, true); - const dataField = fieldProps.Document[Doc.LayoutFieldKey(newDoc)]; + const layoutFieldKey = StrCast(textBox.fieldKey); + const newDoc = Doc.MakeCopy(textBox.Document, true); + const dataField = textBox.Document[Doc.LayoutFieldKey(newDoc)]; newDoc['$' + Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List([]) : undefined; - if (layoutFieldKey !== 'layout' && fieldProps.Document[layoutFieldKey] instanceof Doc) { - newDoc[layoutFieldKey] = fieldProps.Document[layoutFieldKey]; + if (layoutFieldKey !== 'layout' && textBox.Document[layoutFieldKey] instanceof Doc) { + newDoc[layoutFieldKey] = textBox.Document[layoutFieldKey]; } newDoc.$text = undefined; DocumentView.SetSelectOnLoad(newDoc); @@ -574,8 +575,8 @@ export class CollectionStackingView extends CollectionSubView ; + Doc: Doc; + TemplateDataDoc: Opt; docList: Doc[]; heading: string; pivotField: string; @@ -90,7 +90,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< // is that the only way to have drop targets? createColumnDropRef = (ele: HTMLDivElement | null) => { this.dropDisposer?.(); - if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document, this.onInternalPreDrop.bind(this)); + if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Doc, this.onInternalPreDrop.bind(this)); else if (this._ele) this.props.refList.splice(this.props.refList.indexOf(this._ele), 1); this._ele = ele; }; @@ -183,7 +183,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< // TODO: I think this is where I'm supposed to edit stuff startDrag = (e: PointerEvent) => { // is MakeEmbedding a way to make a copy of a doc without rendering it? - const embedding = Doc.MakeEmbedding(this._props.Document); + const embedding = Doc.MakeEmbedding(this._props.Doc); embedding._width = this._props.columnWidth / (this._props.colHeaderData?.length || 1); embedding._pivotField = undefined; let value = this.getValue(this._heading); @@ -230,7 +230,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< ContextMenu.Instance.clearItems(); const layoutItems: ContextMenuProps[] = []; const docItems: ContextMenuProps[] = []; - const dataDoc = this._props.TemplateDataDocument || this._props.Document; + const dataDoc = this._props.TemplateDataDoc || this._props.Doc; const width = this._ele ? DivWidth(this._ele) : 0; const height = this._ele ? DivHeight(this._ele) : 0; DocUtils.addDocumentCreatorMenuItems( @@ -250,10 +250,10 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< docItems.push({ description: ':' + fieldKey, event: () => { - const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document)); + const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Doc)); if (created) { - if (this._props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this._props.Document); + if (this._props.Doc.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Doc); } return this._props.addDocument?.(created); } @@ -270,7 +270,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< event: () => { const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey }); if (created) { - const container = this._props.Document.resolvedDataDoc ? Doc.GetProto(this._props.Document) : this._props.Document; + const container = this._props.Doc.resolvedDataDoc ? Doc.GetProto(this._props.Doc) : this._props.Doc; if (container.isTemplateDoc) { Doc.MakeMetadataFieldTemplate(created, container); return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created); @@ -285,11 +285,11 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' }); !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' }); ContextMenu.Instance.setDefaultItem('::', (name: string): void => { - Doc.GetProto(this._props.Document)[name] = ''; + Doc.GetProto(this._props.Doc)[name] = ''; const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true }); if (created) { - if (this._props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this._props.Document); + if (this._props.Doc.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Doc); } this._props.addDocument?.(created); } @@ -350,10 +350,10 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
) : null; const templatecols = `${this._props.columnWidth / this._props.numGroupColumns}px `; - const { type } = this._props.Document; + const { type } = this._props.Doc; return ( <> - {this._props.Document._columnsHideIfEmpty ? null : headingView} + {this._props.Doc._columnsHideIfEmpty ? null : headingView} {this.collapsed ? null : (
() { constructor(props: X & SubCollectionViewProps) { super(props); makeObservable(this); - console.log(`propsTitle: ${this._props.Document.title} DocTitle: ${this.Document.title} LayoutTitle:${this.layoutDoc.title} DataTitle:${this.dataDoc.title}`); - console.log(`tempTitle: ${this._props.TemplateDataDocument?.title} LayouTResolve: ${DocCast(this.layoutDoc.resolvedDataDoc)?.title} propDocResolve: ${DocCast(this._props.Document.resolvedDataDoc)?.title}`); - console.log('Children:', this.childDocs, this.childLayoutPairs); } @observable _focusFilters: Opt = undefined; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it @@ -111,7 +108,6 @@ export function CollectionSubView() { } get dataDoc() { - console.log(this._props.Document.title + ' isTemplate: ' + this.layoutDoc.isTemplateForField); return this._props.TemplateDataDocument instanceof Doc && this.layoutDoc.isTemplateForField // ? this._props.TemplateDataDocument[DocData] : this.layoutDoc.resolvedDataDoc @@ -135,7 +131,7 @@ export function CollectionSubView() { hasChildDocs = () => this.childLayoutPairs.map(pair => pair.layout); @computed get childLayoutPairs(): { layout: Doc; data: Doc }[] { - const { Document, TemplateDataDocument } = this._props; + const { Document: Document, TemplateDataDocument } = this._props; const validPairs = this.childDocs .map(doc => Doc.GetLayoutDataDocPair(Document, !this._props.isAnnotationOverlay ? TemplateDataDocument : undefined, doc)) .filter( @@ -303,7 +299,7 @@ export function CollectionSubView() { const dragData = de.complete.docDragData; if (dragData) { const sourceDragAction = dragData.dropAction; - const sameCollection = !dragData.draggedDocuments.some(d => d.embedContainer !== this._props.Document); + const sameCollection = !dragData.draggedDocuments.some(d => d.embedContainer !== this._renderDoc); dragData.dropAction = !sameCollection // if doc from another tree ? sourceDragAction || targetDropAction // then use the source's dragAction otherwise the target's : sourceDragAction === dropActionType.inPlace // if source drag is inPlace diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 98bd06221..fd562e64f 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -121,7 +121,7 @@ export class CollectionTimeView extends CollectionSubView() { {this.contents}
{ this.layoutDoc._pivotField = fieldKey; }} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index e93724dd4..b7f49ac20 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -241,7 +241,7 @@ export class CollectionTreeView extends CollectionSubView { + onKey = (e: React.KeyboardEvent /* , textBox: FormattedTextBox */) => { if (this.outlineMode && e.key === 'Enter') { e.stopPropagation(); this.makeTextCollection(this.treeChildren); @@ -252,7 +252,6 @@ export class CollectionTreeView extends CollectionSubView {!(this.Document instanceof Doc) || !this.treeChildren ? null : this.Document.treeView_HasOverlay ? ( DocumentView | undefined; addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean; PanelWidth: () => number; @@ -100,15 +100,15 @@ export class TabMinimapView extends ObservableReactComponent Cast(this._props.document.childLayoutTemplate, Doc, null); - returnMiniSize = () => NumCast(this._props.document._miniMapSize, 150); + childLayoutTemplate = () => Cast(this._props.doc.childLayoutTemplate, Doc, null); + returnMiniSize = () => NumCast(this._props.doc._miniMapSize, 150); miniDown = (e: React.PointerEvent) => { - const doc = this._props.document; + const doc = this._props.doc; const miniSize = this.returnMiniSize(); doc && setupMoveUpEvents( @@ -127,15 +127,15 @@ export class TabMinimapView extends ObservableReactComponent { const { renderBounds } = this; if (!renderBounds) return
; - const miniWidth = () => (this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100; - const miniHeight = () => (this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100; - const miniLeft = () => 50 + ((NumCast(this._props.document._freeform_panX) - renderBounds.cx) / renderBounds.dim) * 100 - miniWidth() / 2; - const miniTop = () => 50 + ((NumCast(this._props.document._freeform_panY) - renderBounds.cy) / renderBounds.dim) * 100 - miniHeight() / 2; + const miniWidth = () => (this._props.PanelWidth() / NumCast(this._props.doc._freeform_scale, 1) / renderBounds.dim) * 100; + const miniHeight = () => (this._props.PanelHeight() / NumCast(this._props.doc._freeform_scale, 1) / renderBounds.dim) * 100; + const miniLeft = () => 50 + ((NumCast(this._props.doc._freeform_panX) - renderBounds.cx) / renderBounds.dim) * 100 - miniWidth() / 2; + const miniTop = () => 50 + ((NumCast(this._props.doc._freeform_panY) - renderBounds.cy) / renderBounds.dim) * 100 - miniHeight() / 2; const miniSize = this.returnMiniSize(); return (
} color={SnappingManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement="top-end" popup={this.popup} />
@@ -631,7 +631,7 @@ export class TabDocView extends ObservableReactComponent { }}> {!this._activated || !this._document ? null : this.renderDocView(this._document)} {this.disableMinimap() || !this._document ? null : ( - + )}
); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index 35c6d30fe..89d2bf2c3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -12,8 +12,8 @@ import { CollectionFreeFormView } from './CollectionFreeFormView'; import './CollectionFreeFormView.scss'; export interface CollectionFreeFormInfoUIProps { - Document: Doc; - LayoutDoc: Doc; + Doc: Doc; + layoutDoc: Doc; childDocs: () => Doc[]; close: () => void; } @@ -23,7 +23,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent Doc[], close: () => void) => ( // - + )); } _firstDocPos = { x: 0, y: 0 }; @@ -40,7 +40,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent {this._currState = val;}); } // prettier-ignore componentWillUnmount(): void { - this._props.Document.$backgroundColor = this._originalbackground; + this._props.Doc.$backgroundColor = this._originalbackground; } setCurrState = (state: infoState) => { @@ -51,10 +51,10 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent { - this._originalbackground = StrCast(this._props.Document.$backgroundColor); + this._originalbackground = StrCast(this._props.Doc.$backgroundColor); // state entry functions - // const setBackground = (colour: string) => () => {this._props.Document.$backgroundColor = colour;} // prettier-ignore - // const setOpacity = (opacity: number) => () => {this._props.LayoutDoc.opacity = opacity;} // prettier-ignore + // const setBackground = (colour: string) => () => {this._props.Doc.$backgroundColor = colour;} // prettier-ignore + // const setOpacity = (opacity: number) => () => {this._props.layoutDoc.opacity = opacity;} // prettier-ignore // arc transition trigger conditions const firstDoc = () => (this._props.childDocs().length ? this._props.childDocs()[0] : undefined); const numDocs = () => this._props.childDocs().length; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx index bc9dd022c..2683d9439 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx @@ -7,7 +7,7 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import './CollectionFreeFormView.scss'; export interface CollectionFreeFormPannableContentsProps { - Document: Doc; + Doc: Doc; viewDefDivClick?: ScriptField; children?: React.ReactNode | undefined; transition: () => string; @@ -33,7 +33,7 @@ export class CollectionFreeFormPannableContents extends ObservableReactComponent makeObservable(this); } @computed get presPaths() { - return this._props.showPresPaths() ? CollectionFreeFormPannableContents._overlayPlugin?.(this._props.Document) : null; + return this._props.showPresPaths() ? CollectionFreeFormPannableContents._overlayPlugin?.(this._props.Doc) : null; } // rectangle highlight used when following trail/link to a region of a collection that isn't a document showViewport = (viewport: { panX: number; panY: number; width: number; height: number } | undefined) => diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx index f64c6715b..86310dca3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx @@ -13,7 +13,7 @@ import './CollectionFreeFormView.scss'; @observer export class CollectionFreeFormRemoteCursors extends React.Component { @computed protected get cursors(): CursorField[] { - const { Document } = this.props; + const { Document: Document } = this.props; const cursors = Cast(Document.cursors, listSpec(CursorField)); if (!cursors) { return []; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 6030e146c..25cec9c0d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,10 +1,13 @@ -import { Bezier } from 'bezier-js'; import { Button, Colors, Type } from '@dash/components'; +import { Slider } from '@mui/material'; +import { Bezier } from 'bezier-js'; import { Property } from 'csstype'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; +import { AiOutlineSend } from 'react-icons/ai'; +import ReactLoading from 'react-loading'; import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; @@ -28,6 +31,7 @@ import { DragManager } from '../../../util/DragManager'; import { dropActionType } from '../../../util/DropActionTypes'; import { CompileScript } from '../../../util/Scripting'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; +import { SettingsManager } from '../../../util/SettingsManager'; import { freeformScrollMode, SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -37,26 +41,26 @@ import { InkingStroke } from '../../InkingStroke'; import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView'; import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp'; import { + ActiveEraserWidth, ActiveInkArrowEnd, ActiveInkArrowStart, - ActiveInkDash, - ActiveEraserWidth, - ActiveInkFillColor, ActiveInkBezierApprox, ActiveInkColor, + ActiveInkDash, + ActiveInkFillColor, ActiveInkWidth, ActiveIsInkMask, DocumentView, SetActiveInkColor, SetActiveInkWidth, } from '../../nodes/DocumentView'; -import { FieldViewProps } from '../../nodes/FieldView'; import { FocusViewOptions } from '../../nodes/FocusViewOptions'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { OpenWhere } from '../../nodes/OpenWhere'; import { PinDocView, PinProps } from '../../PinFuncs'; -import { StickerPalette } from '../../smartdraw/StickerPalette'; +import { DrawingFillHandler } from '../../smartdraw/DrawingFillHandler'; import { DrawingOptions, SmartDrawHandler } from '../../smartdraw/SmartDrawHandler'; +import { StickerPalette } from '../../smartdraw/StickerPalette'; import { StyleProp } from '../../StyleProp'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import { TreeViewType } from '../CollectionTreeViewType'; @@ -67,11 +71,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors'; import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; -import ReactLoading from 'react-loading'; -import { SettingsManager } from '../../../util/SettingsManager'; -import { Slider } from '@mui/material'; -import { AiOutlineSend } from 'react-icons/ai'; -import { DrawingFillHandler } from '../../smartdraw/DrawingFillHandler'; @observer class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> { @@ -180,10 +179,10 @@ export class CollectionFreeFormView extends CollectionSubView this.fitContentBounds?.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1)); - panY = () => this.fitContentBounds?.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1)); + panX = () => this.fitContentBounds?.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(this.Document.freeform_panX, 1)); + panY = () => this.fitContentBounds?.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(this.Document.freeform_panY, 1)); zoomScaling = () => this.fitContentBounds?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1)); PanZoomCenterXf = () => (this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.centeringShiftX}px, ${this.centeringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`); ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy(); @@ -1489,20 +1488,20 @@ export class CollectionFreeFormView extends CollectionSubView { - const textDoc = DocCast(fieldProps.Document.rootDocument, fieldProps.Document); + createTextDocCopy = undoable((textBox: FormattedTextBox, below: boolean) => { + const textDoc = DocCast(textBox.Document.rootDocument, textBox.Document); const newDoc = Doc.MakeCopy(textDoc, true); - newDoc['$' + Doc.LayoutFieldKey(newDoc, fieldProps.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style + newDoc['$' + Doc.LayoutFieldKey(newDoc, textBox._props.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style newDoc.x = NumCast(textDoc.x) + (below ? 0 : NumCast(textDoc._width) + 10); newDoc.y = NumCast(textDoc.y) + (below ? NumCast(textDoc._height) + 10 : 0); DocumentView.SetSelectOnLoad(newDoc); return this.addDocument?.(newDoc); }, 'copied text note'); - onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => { - if ((e.metaKey || e.ctrlKey || e.altKey || fieldProps.Document._createDocOnCR) && ['Tab', 'Enter'].includes(e.key)) { + onKeyDown = (e: React.KeyboardEvent, textBox: FormattedTextBox) => { + if ((e.metaKey || e.ctrlKey || e.altKey || textBox.Document._createDocOnCR) && ['Tab', 'Enter'].includes(e.key)) { e.stopPropagation?.(); - return this.createTextDocCopy(fieldProps, !e.altKey && e.key !== 'Tab'); + return this.createTextDocCopy(textBox, !e.altKey && e.key !== 'Tab'); } return undefined; }; @@ -1685,7 +1684,7 @@ export class CollectionFreeFormView extends CollectionSubView (this._props.Document.isTemplateDoc || this._props.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); + renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc || this.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); doEngineLayout( poolData: Map, @@ -2115,7 +2114,7 @@ export class CollectionFreeFormView extends CollectionSubView 0 ? undefined : this.nudge} addDocTab={this.addDocTab} @@ -2149,7 +2149,7 @@ export class CollectionFreeFormView extends CollectionSubView {this.layoutDoc._freeform_backgroundGrid ? this.backgroundGrid : null} {this.pannableContents} - {this._showAnimTimeline ? : null} + {this._showAnimTimeline ? : null} ); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index e3f4c6605..eaa8826ed 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -32,6 +32,7 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; interface MarqueeViewProps { + Doc: Doc; getContainerTransform: () => Transform; getTransform: () => Transform; activeDocuments: () => Doc[]; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index e89822b4c..daffdf1f5 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -21,11 +21,11 @@ import DOMPurify from 'dompurify'; */ export interface SchemaCellFieldProps { + Doc: Doc; contents: FieldType | undefined; fieldContents?: FieldViewProps; editing?: boolean; oneLine?: boolean; - Document: Doc; fieldKey: string; // eslint-disable-next-line no-use-before-define refSelectModeInfo: { enabled: boolean; currEditing: SchemaCellField | undefined }; @@ -55,7 +55,7 @@ export class SchemaCellField extends ObservableReactComponent() { isolatedSelection={this.isolatedSelection} key={key} rowSelected={this._props.isSelected} - Document={this.Document} + Doc={this.Document} col={index} fieldKey={key} allowCRs={false} // to enter text with new lines, must use \n diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 1b4f200a3..e6fe46638 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -40,7 +40,7 @@ import { SchemaCellField } from './SchemaCellField'; */ export interface SchemaTableCellProps { - Document: Doc; + Doc: Doc; col: number; deselectCell: () => void; selectCell: (doc: Doc, col: number, shift: boolean, ctrl: boolean) => void; @@ -71,7 +71,7 @@ export interface SchemaTableCellProps { } function selectedCell(props: SchemaTableCellProps) { - return props.isRowActive() && props.selectedCol() === props.col && props.selectedCells()?.filter(d => d === props.Document)?.length; + return props.isRowActive() && props.selectedCol() === props.col && props.selectedCells()?.filter(d => d === props.Doc)?.length; } @observer @@ -84,11 +84,11 @@ export class SchemaTableCell extends ObservableReactComponent this._props.highlightCells(this.adjustSelfReference(text))} getCells={(text: string) => this._props.eqHighlightFunc(this.adjustSelfReference(text))} ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} @@ -224,7 +224,7 @@ export class SchemaTableCell extends ObservableReactComponent = []; sides[0] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // left sides[1] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // right - sides[2] = !this._props.isolatedSelection(this._props.Document)[0] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top - sides[3] = !this._props.isolatedSelection(this._props.Document)[1] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom + sides[2] = !this._props.isolatedSelection(this._props.Doc)[0] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top + sides[3] = !this._props.isolatedSelection(this._props.Doc)[1] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom return sides; } @@ -272,7 +272,7 @@ export class SchemaTableCell extends ObservableReactComponent Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url) .filter(url => url) @@ -359,7 +359,7 @@ export class SchemaImageCell extends ObservableReactComponent { @@ -388,7 +388,7 @@ export class SchemaDateCell extends ObservableReactComponent e.stopPropagation()} style={{ marginRight: 4 }} type="checkbox" - checked={BoolCast(this._props.Document[this._props.fieldKey])} + checked={BoolCast(this._props.Doc[this._props.fieldKey])} onChange={undoable((value: React.ChangeEvent | undefined) => { if ((value?.nativeEvent as MouseEvent | PointerEvent).shiftKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); - } else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); + } else Doc.SetField(this._props.Doc, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); }, 'set bool cell')} /> @@ -463,14 +463,14 @@ export class SchemaBoolCell extends ObservableReactComponent Field.toKeyValueString(this._props.Document, this._props.fieldKey)} + GetValue={() => Field.toKeyValueString(this._props.Doc, this._props.fieldKey)} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); this._props.finishEdit?.(); return true; } - const set = Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined); + const set = Doc.SetField(this._props.Doc, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Doc) ? true : undefined); this._props.finishEdit?.(); return set; }, 'set bool cell')} @@ -538,10 +538,10 @@ export class SchemaEnumerationCell extends ObservableReactComponent Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)} + onChange={val => Doc.SetField(this._props.Doc, this._props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)} />
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index ce1e9280a..6f86383c2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -304,7 +304,7 @@ export class CollectionFreeFormDocumentView extends DocComponent val.lower)).omit} // prettier-ignore - Document={this._props.Document} + Document={this._renderDoc} renderDepth={this._props.renderDepth} isContentActive={this._props.isContentActive} childFilters={this._props.childFilters} diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index d5e37b3b5..117eb05f8 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -1,43 +1,39 @@ +import { Colors, Toggle, ToggleType, Type } from '@dash/components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox } from '@mui/material'; -import { Colors, Toggle, ToggleType, Type } from '@dash/components'; import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ClientUtils, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils'; +import { returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; -import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit } from '../../../../fields/DocSymbols'; +import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; -import { PrefetchProxy } from '../../../../fields/Proxy'; import { Cast, CsvCast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; import { CsvField } from '../../../../fields/URLField'; -import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util'; +import { TraceMobx } from '../../../../fields/util'; import { GPTCallType, gptAPICall } from '../../../apis/gpt/GPT'; import { DocUtils } from '../../../documents/DocUtils'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; -import { LinkManager } from '../../../util/LinkManager'; import { UndoManager, undoable } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { MarqueeAnnotator } from '../../MarqueeAnnotator'; import { PinProps } from '../../PinFuncs'; import { SidebarAnnos } from '../../SidebarAnnos'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { AnchorMenu } from '../../pdf/AnchorMenu'; import { GPTPopup, GPTPopupMode } from '../../pdf/GPTPopup/GPTPopup'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; import './DataVizBox.scss'; -import { Col, DataVizTemplateInfo, DocCreatorMenu, LayoutType} from './DocCreatorMenu/DocCreatorMenu'; +import { Col, DocCreatorMenu } from './DocCreatorMenu/DocCreatorMenu'; +import { TemplateFieldSize, TemplateFieldType } from './DocCreatorMenu/TemplateBackend'; import { Histogram } from './components/Histogram'; import { LineChart } from './components/LineChart'; import { PieChart } from './components/PieChart'; import { TableBox } from './components/TableBox'; -import { TemplateFieldSize, TemplateFieldType } from './DocCreatorMenu/TemplateBackend'; export enum DataVizView { TABLE = 'table', @@ -440,10 +436,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { }; if (!this.records.length) return 'no data/visualization'; switch (this.dataVizView) { - case DataVizView.TABLE: return ; - case DataVizView.LINECHART: return {this._vizRenderer = r ?? undefined;}} vizBox={this} />; - case DataVizView.HISTOGRAM: return {this._vizRenderer = r ?? undefined;}} />; - case DataVizView.PIECHART: return {this._vizRenderer = r ?? undefined;}} + case DataVizView.TABLE: return ; + case DataVizView.LINECHART: return {this._vizRenderer = r ?? undefined;}} vizBox={this} />; + case DataVizView.HISTOGRAM: return {this._vizRenderer = r ?? undefined;}} />; + case DataVizView.PIECHART: return {this._vizRenderer = r ?? undefined;}} margin={{ top: 10, right: 15, bottom: 15, left: 15 }} />; default: } // prettier-ignore @@ -574,9 +570,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { const cols = Array.from(Object.keys(this.records[0])).filter(header => header !== '' && header !== undefined); - cols.forEach(col => { - this.setColumnDefault(col, `${this.records[rowToCheck][col]}`); - }); + cols.forEach(col => this.setColumnDefault(col, `${this.records[rowToCheck][col]}`)); }; updateGPTSummary = async () => { @@ -706,7 +700,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { ref={this._sidebarRef} {...this._props} fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 5a9442d2f..776d65211 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -17,7 +17,7 @@ import { scaleCreatorNumerical, yAxisCreator } from '../utils/D3Utils'; import './Chart.scss'; export interface HistogramProps { - Document: Doc; + Doc: Doc; layoutDoc: Doc; axes: string[]; titleCol: string; @@ -88,7 +88,7 @@ export class Histogram extends ObservableReactComponent { } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } @computed get rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } { @@ -126,7 +126,7 @@ export class Histogram extends ObservableReactComponent { const anchor = Docs.Create.ConfigDocument({ title: 'histogram doc selection' + this._currSelected, }); - PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); + PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Doc); return anchor; }; @@ -416,11 +416,9 @@ export class Histogram extends ObservableReactComponent { let barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); barColors.forEach(each => { - // eslint-disable-next-line prefer-destructuring if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1]; else { const range = StrCast(each[0]).split(' to '); - // eslint-disable-next-line prefer-destructuring if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1]; } }); @@ -454,11 +452,9 @@ export class Histogram extends ObservableReactComponent { let barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); barColors.forEach(each => { - // eslint-disable-next-line prefer-destructuring if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1]; else { const range = StrCast(each[0]).split(' to '); - // eslint-disable-next-line prefer-destructuring if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1]; } }); @@ -471,7 +467,7 @@ export class Histogram extends ObservableReactComponent { this.updateSavedUI(); this._histogramData; let curSelectedBarName = ''; - let titleAccessor: any = 'dataViz_histogram_title'; + let titleAccessor = 'dataViz_histogram_title'; if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0]; if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; @@ -503,7 +499,6 @@ export class Histogram extends ObservableReactComponent { let selectedBarColor; const barColors = StrListCast(this._props.layoutDoc.histogramBarColors).map(each => each.split('::')); barColors.forEach(each => { - // eslint-disable-next-line prefer-destructuring each[0] === curSelectedBarName && (selectedBarColor = each[1]); }); diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index b55d509ff..6b047546c 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -22,7 +22,7 @@ export interface SelectedDataPoint extends DataPoint { } export interface LineChartProps { vizBox: DataVizBox; - Document: Doc; + Doc: Doc; layoutDoc: Doc; axes: string[]; titleCol: string; @@ -53,7 +53,7 @@ export class LineChart extends ObservableReactComponent { } @computed get titleAccessor() { - let titleAccessor: any = 'dataViz_lineChart_title'; + let titleAccessor = 'dataViz_lineChart_title'; if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0]; return titleAccessor; @@ -74,7 +74,7 @@ export class LineChart extends ObservableReactComponent { return this._props.axes[1] + ' vs. ' + this._props.axes[0] + ' Line Chart'; } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } @computed get incomingHighlited() { // return selected x and y axes @@ -113,7 +113,7 @@ export class LineChart extends ObservableReactComponent { // title: 'line doc selection' + (this._currSelected?.x ?? ''), }); - PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); + PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Doc); anchor.config_dataVizSelection = this._currSelected ? new List([this._currSelected.x, this._currSelected.y]) : undefined; return anchor; }; diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index 86e6ad8e4..0ae70786f 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -16,7 +16,7 @@ import { PinProps, PinDocView } from '../../../PinFuncs'; import './Chart.scss'; export interface PieChartProps { - Document: Doc; + Doc: Doc; layoutDoc: Doc; axes: string[]; titleCol: string; @@ -83,7 +83,7 @@ export class PieChart extends ObservableReactComponent { } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } componentWillUnmount() { @@ -114,7 +114,7 @@ export class PieChart extends ObservableReactComponent { // title: 'piechart doc selection' + this._currSelected, }); - PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); + PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Doc); return anchor; }; @@ -169,7 +169,6 @@ export class PieChart extends ObservableReactComponent { // inside the slice of it crosses an odd number of edges const showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index]; let key = 'data'; // key that represents slice - // eslint-disable-next-line prefer-destructuring if (Object.keys(showSelected)[0] === 'frequency') key = Object.keys(showSelected)[1]; if (changeSelectedVariables) { let sameAsAny = false; @@ -296,7 +295,7 @@ export class PieChart extends ObservableReactComponent { if (descriptionField) dataPointVal[descriptionField] = each[descriptionField]; try { dataPointVal[percentField] = Number(dataPointVal[percentField].replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/ { // to make sure all important slice information is on 'd' object let addKey: any = false; if (pieDataSet.length && Object.keys(pieDataSet[0])[0] === 'frequency') { - // eslint-disable-next-line prefer-destructuring addKey = Object.keys(pieDataSet[0])[1]; } arcs.append('path') @@ -324,7 +322,6 @@ export class PieChart extends ObservableReactComponent { const sliceTitle = dataPoint[this._props.axes[0]]; const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/ { - // eslint-disable-next-line prefer-destructuring each[0] === accessByName && (sliceColor = each[1]); }); } @@ -337,7 +334,7 @@ export class PieChart extends ObservableReactComponent { }); return selectThisData ? 'slice hover' : 'slice'; }) - // @ts-ignore + // @ts-expect-error types don't match .attr('d', arc) .on('click', onPointClick) .on('mouseover', onHover) @@ -388,7 +385,7 @@ export class PieChart extends ObservableReactComponent { }; render() { - let titleAccessor: any = 'dataViz_pie_title'; + let titleAccessor = 'dataViz_pie_title'; if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0]; if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; @@ -420,7 +417,6 @@ export class PieChart extends ObservableReactComponent { let selectedSliceColor; const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::')); sliceColors.forEach(each => { - // eslint-disable-next-line prefer-destructuring if (each[0] === curSelectedSliceName!) selectedSliceColor = each[1]; }); diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index b6183946a..b73123691 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -19,7 +19,7 @@ import './Chart.scss'; const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore interface TableBoxProps { - Document: Doc; + Doc: Doc; layoutDoc: Doc; records: { [key: string]: unknown }[]; selectAxes: (axes: string[]) => void; @@ -81,7 +81,7 @@ export class TableBox extends ObservableReactComponent { } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } @computed get columns() { @@ -139,21 +139,21 @@ export class TableBox extends ObservableReactComponent { e, moveEv => { // dragging off a column to create a brushed DataVizBox - const sourceAnchorCreator = () => this._props.docView?.()?.Document || this._props.Document; + const sourceAnchorCreator = () => this._props.docView?.()?.Document || this._props.Doc; const targetCreator = (annotationOn: Doc | undefined) => { const doc = this._props.docView?.()?.Document; if (doc) { const embedding = Doc.MakeEmbedding(doc); embedding._dataViz = DataVizView.TABLE; embedding._dataViz_axes = new List([col]); - embedding._dataViz_parentViz = this._props.Document; + embedding._dataViz_parentViz = this._props.Doc; embedding.annotationOn = annotationOn; embedding.histogramBarColors = Field.Copy(this._props.layoutDoc.histogramBarColors); embedding.defaultHistogramColor = this._props.layoutDoc.defaultHistogramColor; embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors); return embedding; } - return this._props.Document; + return this._props.Doc; }; if (this._props.docView?.() && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) { DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e9353b001..c355e57d4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -758,7 +758,7 @@ export class DocumentViewInternal extends DocComponent { this._changingTitleField = true; })} // prettier-ignore style={{ width: 'max-content', background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}> { if (this.layoutDoc.layout_showTitle) { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 2e40f39ed..abba99c3d 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -15,6 +15,7 @@ import { FocusViewOptions } from './FocusViewOptions'; import { OpenWhere } from './OpenWhere'; import { WebField } from '../../../fields/URLField'; import { ContextMenuProps } from '../ContextMenuItem'; +import { FormattedTextBox } from './formattedText/FormattedTextBox'; export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt; export type StyleProviderFuncType = ( @@ -83,8 +84,7 @@ export interface FieldViewSharedProps { onDoubleClickScript?: () => ScriptField; onPointerDownScript?: () => ScriptField; onPointerUpScript?: () => ScriptField; - // eslint-disable-next-line no-use-before-define - onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined; + onKey?: (e: React.KeyboardEvent, textBox: FormattedTextBox) => boolean | undefined; fitWidth?: (doc: Doc) => boolean | undefined; dontCenter?: 'x' | 'y' | 'xy' | undefined; searchFilterDocs: () => Doc[]; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5d9718760..d121b492f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -648,7 +648,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { onClick={action(async () => { this._regenerateLoading = true; if (this._fireflyRefStrength) { - DrawingFillHandler.drawingToImage(this.props.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title), this.Document)?.then(action(() => (this._regenerateLoading = false))); + DrawingFillHandler.drawingToImage(this.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title), this.Document)?.then(action(() => (this._regenerateLoading = false))); } else { SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput || StrCast(this.Document.title), true).then( action(newImgs => { diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 32c9efbd9..8911fac6d 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -58,8 +58,8 @@ export class KeyValueBox extends ViewBoxBaseComponent() { onEnterKey = (e: React.KeyboardEvent): void => { if (e.key === 'Enter') { e.stopPropagation(); - if (this._keyInput.current?.value && this._valInput.current?.value && this._props.Document) { - if (KeyValueBox.SetField(this._props.Document, this._keyInput.current.value, this._valInput.current.value)) { + if (this._keyInput.current?.value && this._valInput.current?.value && this.Document) { + if (KeyValueBox.SetField(this.Document, this._keyInput.current.value, this._valInput.current.value)) { this._keyInput.current.value = ''; this._valInput.current.value = ''; document.body.focus(); @@ -137,7 +137,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { rowHeight = () => 30; @computed get createTable() { - const doc = this._props.Document; + const doc = this.Document; if (!doc) { return ( @@ -305,8 +305,8 @@ export class KeyValueBox extends ViewBoxBaseComponent() { openItems.push({ description: 'Default Perspective', event: () => { - this._props.addDocTab(this._props.Document, OpenWhere.close); - this._props.addDocTab(this._props.Document, OpenWhere.addRight); + this._props.addDocTab(this.Document, OpenWhere.close); + this._props.addDocTab(this.Document, OpenWhere.addRight); }, icon: 'image', }); diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 65d78f754..a563b7c1b 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1300,7 +1300,7 @@ export class MapBox extends ViewBoxAnnotatableComponent() { ref={this._sidebarRef} {...this._props} fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx index ddeaf4d0d..e0efab576 100644 --- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx +++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx @@ -798,7 +798,6 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent PanelHeight={returnOne} NativeWidth={returnOne} NativeHeight={returnOne} - onKey={undefined} onDoubleClickScript={undefined} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} @@ -830,7 +829,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent ref={this._sidebarRef} {...this._props} fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 5484179be..78ddafa88 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -535,7 +535,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { () { pdfBox={this} sidebarAddDoc={this.sidebarAddDocument} addDocTab={this.sidebarAddDocTab} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} pdf={this._pdf} diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 6289470b6..999f9c1cd 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -301,7 +301,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent()
()
{!(this.dataDoc[this.fieldKey + '_dictation'] instanceof Doc) ? null : ( () { {...this._props} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} fieldKey={this.fieldKey + '_' + this._urlHash} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} setHeight={emptyFunction} diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index aa2829aaf..bb0efa917 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -162,7 +162,7 @@ export class DashFieldViewInternal extends ObservableReactComponent (this._expanded ? true : undefined)} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 9078648e9..925109bfb 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -78,14 +78,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent new FormattedTextBoxComment() }), @@ -153,7 +153,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { let mapStyle = assignedMapStyle; - tx2.doc.descendants((node: any, offset: any /* , index: any */) => { + tx2.doc.descendants((node: Node, offset: number /* , index: any */) => { if ((from === undefined || to === undefined || (from <= offset + node.nodeSize && to >= offset)) && (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item)) { - const { path } = tx2.doc.resolve(offset) as any; - let depth = Array.from(path).reduce((p: number, c: any) => p + (c.type === schema.nodes.ordered_list ? 1 : 0), 0); + const { path } = tx2.doc.resolve(offset) as unknown as { path: (number | Node)[] }; // bcz: can't access path .. need to FIX + let depth = Array.from(path).reduce((p: number, c: number | Node) => p + ((c as Node).type === schema.nodes.ordered_list ? 1 : 0), 0); if (node.type === schema.nodes.ordered_list) { if (depth === 0 && !assignedMapStyle) mapStyle = node.attrs.mapStyle; depth++; @@ -34,25 +35,25 @@ export const updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle return tx2; }; -export function buildKeymap>(schema: S, props: any): KeyMap { - const keys: { [key: string]: any } = {}; +export function buildKeymap>(schema: S, tbox?: FormattedTextBox): KeyMap { + const keys: { [key: string]: Command } = {}; - function bind(key: string, cmd: any) { + function bind(key: string, cmd: Command) { keys[key] = cmd; } function onKey(): boolean | undefined { // bcz: this is pretty hacky -- prosemirror doesn't send us the keyboard event, but the 'event' variable is in scope.. so we access it anyway - // eslint-disable-next-line no-restricted-globals - return props.onKey?.(event, props); + return tbox?._props.onKey?.(event, tbox); } - const canEdit = (state: any) => { - const permissions = GetEffectiveAcl(props.TemplateDataDocument ?? props.Document[DocData]); + const canEdit = (state: EditorState) => { + if (!tbox) return true; + const permissions = GetEffectiveAcl(tbox._props.TemplateDataDocument ?? tbox.Document[DocData]); switch (permissions) { case AclAugment: { - const prevNode = state.selection.$cursor.nodeBefore; + const prevNode = (state.selection as any).$cursor.nodeBefore; const prevUser = !prevNode ? ClientUtils.CurrentUserEmail() : prevNode.marks.lastElement()?.attrs.userid; if (prevUser !== ClientUtils.CurrentUserEmail()) { return false; @@ -64,7 +65,7 @@ export function buildKeymap>(schema: S, props: any): KeyMa return true; }; - const toggleEditableMark = (mark: any) => (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && toggleMark(mark)(state, dispatch); + const toggleEditableMark = (mark: MarkType) => (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && toggleMark(mark)(state, dispatch); // History commands bind('Mod-z', undo); @@ -84,13 +85,13 @@ export function buildKeymap>(schema: S, props: any): KeyMa bind('Mod-U', toggleEditableMark(schema.marks.underline)); // Commands for lists - bind('Ctrl-i', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any)); + bind('Ctrl-i', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state, dispatch)); bind('Ctrl-Tab', () => onKey() || true); bind('Alt-Tab', () => onKey() || true); bind('Meta-Tab', () => onKey() || true); bind('Meta-Enter', () => onKey() || true); - bind('Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Tab', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (onKey()) return true; if (!canEdit(state)) return true; const ref = state.selection; @@ -101,13 +102,13 @@ export function buildKeymap>(schema: S, props: any): KeyMa const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); }) ) { // couldn't sink into an existing list, so wrap in a new one const newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end))); if ( - !wrapInList(schema.nodes.ordered_list)(newstate.state as any, (tx2: Transaction) => { + !wrapInList(schema.nodes.ordered_list)(newstate.state, (tx2: Transaction) => { const tx25 = updateBullets(tx2, schema); const olNode = tx25.doc.nodeAt(range!.start)!; const tx3 = tx25.setNodeMarkup(range!.start, olNode.type, olNode.attrs, marks); @@ -115,16 +116,16 @@ export function buildKeymap>(schema: S, props: any): KeyMa marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); const tx4 = tx3.setSelection(TextSelection.near(tx3.doc.resolve(state.selection.to + 2))); - dispatch(tx4); + dispatch?.(tx4); }) ) { console.log('bullet promote fail'); } } - return undefined; + return false; }); - bind('Shift-Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Shift-Tab', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (onKey()) return true; if (!canEdit(state)) return true; const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); @@ -134,72 +135,83 @@ export function buildKeymap>(schema: S, props: any): KeyMa const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); }) ) { console.log('bullet demote fail'); } - return undefined; + return false; }); // Command to create a new Tab with a PDF of all the command shortcuts - bind('Mod-/', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + bind('Mod-/', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { const newDoc = Docs.Create.PdfDocument(ClientUtils.prepend('/assets/cheat-sheet.pdf'), { _width: 300, _height: 300 }); - props.addDocTab(newDoc, OpenWhere.addRight); + tbox?._props.addDocTab(newDoc, OpenWhere.addRight); + return false; }); // Commands to modify BlockType - bind('Ctrl->', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state && wrapIn(schema.nodes.blockquote)(state as any, dispatch as any))); - bind('Alt-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state as any, dispatch as any)); - bind('Shift-Ctrl-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.code_block)(state as any, dispatch as any)); + bind('Ctrl->', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && wrapIn(schema.nodes.blockquote)(state, dispatch)); + bind('Alt-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state, dispatch)); + bind('Shift-Ctrl-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.code_block)(state, dispatch)); - bind('Ctrl-m', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Ctrl-m', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (canEdit(state)) { const tr = state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: 'math' + Utils.GenerateGuid() })); - dispatch(tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)))); + dispatch?.(tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)))); + return true; } + return false; }); for (let i = 1; i <= 6; i++) { - bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state as any, dispatch as any)); + bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state, dispatch)); } // Command to create a horizontal break line const hr = schema.nodes.horizontal_rule; - bind('Mod-_', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView())); + bind('Mod-_', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + if (canEdit(state)) { + dispatch?.(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); + return true; + } + return false; + }); // Command to unselect all - bind('Escape', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); - (document.activeElement as any).blur?.(); + bind('Escape', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); + (document.activeElement as HTMLElement)?.blur?.(); DocumentView.DeselectAll(); + return true; }); bind('Alt-Enter', () => onKey() || true); bind('Ctrl-Enter', () => onKey() || true); - bind('Cmd-a', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); + bind('Cmd-a', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); return true; }); bind('Cmd-?', () => { RTFMarkup.Instance.setOpen(true); return true; }); - bind('Cmd-e', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Cmd-e', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (!state.selection.empty) { const mark = state.schema.marks.summarizeInclusive.create(); const tr = state.tr.addMark(state.selection.$from.pos, state.selection.$to.pos, mark); const content = tr.selection.content(); - tr.selection.replaceWith(tr, schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() })); - dispatch(tr); + tr.selection.replaceWith(tr, schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() }, undefined, state.selection.$anchor.marks() ?? [])); + dispatch?.(tr); } return true; }); - bind('Cmd-]', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; + bind('Cmd-]', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible const { tr } = state; if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); + tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); } else { const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -207,14 +219,14 @@ export function buildKeymap>(schema: S, props: any): KeyMa tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; + bind('Cmd-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible const { tr } = state; if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); + tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); } else { const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -222,14 +234,14 @@ export function buildKeymap>(schema: S, props: any): KeyMa tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-[', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; + bind('Cmd-[', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible const { tr } = state; if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); + tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); } else { const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -237,16 +249,16 @@ export function buildKeymap>(schema: S, props: any): KeyMa tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-f', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Cmd-f', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { const content = state.tr.selection.empty ? undefined : state.tr.selection.content().content.textBetween(0, state.tr.selection.content().size + 1); const newNode = schema.nodes.footnote.create({}, content ? state.schema.text(content) : undefined); const { tr } = state; tr.replaceSelectionWith(newNode); // replace insertion with a footnote. - dispatch( + dispatch?.( tr.setSelection( new NodeSelection( // select the footnote node to open its display tr.doc.resolve( @@ -259,25 +271,25 @@ export function buildKeymap>(schema: S, props: any): KeyMa return true; }); - bind('Ctrl-a', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); + bind('Ctrl-a', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); return true; }); // backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward); - const backspace = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView) => { + const backspace = (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined, view?: EditorView) => { if (onKey()) return true; if (!canEdit(state)) return true; if ( !deleteSelection(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); + dispatch?.(updateBullets(tx, schema)); }) ) { if ( !joinBackward(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); - if (view.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) { + dispatch?.(updateBullets(tx, schema)); + if (view?.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) { // gets rid of an extra paragraph when joining two list items together. joinBackward(view.state, (tx2: Transaction) => view.dispatch(tx2)); } @@ -285,7 +297,7 @@ export function buildKeymap>(schema: S, props: any): KeyMa ) { if ( !selectNodeBackward(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); + dispatch?.(updateBullets(tx, schema)); }) ) { return false; @@ -299,7 +311,7 @@ export function buildKeymap>(schema: S, props: any): KeyMa // newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock // command to break line - const enter = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView, once = true) => { + const enter = (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined, view?: EditorView, once = true) => { if (onKey()) return true; if (!canEdit(state)) return true; @@ -311,31 +323,31 @@ export function buildKeymap>(schema: S, props: any): KeyMa !state.selection.$from.node().content.size && trange ) { - dispatch(state.tr.lift(trange, depth) as any); + dispatch?.(state.tr.lift(trange, depth)); return true; } const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); - if (!newlineInCode(state, dispatch as any)) { - const olNode = view.state.selection.$anchor.node(-2); - const liNode = view.state.selection.$anchor.node(-1); + if (!newlineInCode(state, dispatch)) { + const olNode = view?.state.selection.$anchor.node(-2); + const liNode = view?.state.selection.$anchor.node(-1); // prettier-ignore if (liNode?.type === schema.nodes.list_item && !liNode.textContent && - olNode?.type === schema.nodes.ordered_list && once && view.state.selection.$from.depth === 3) + olNode?.type === schema.nodes.ordered_list && once && view?.state.selection.$from.depth === 3) { // handles case of hitting enter at then end of a top-level empty list item - the result is to create a paragraph - for (let i = 0; i < 10 && view.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++); + for (let i = 0; i < 10 && view?.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++); } else if ( - !splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => { + !splitListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); // removes an extra paragraph created when selecting text across two list items or splitting an empty list item - !once && view.dispatch(view.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2)); + !once && view?.dispatch(view?.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2)); }) ) { - if (once && view.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') { + if (once && view?.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view?.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') { // handles case of hitting enter on an empty list item which needs to create a second empty paragraph, then split it by calling enter() again view.dispatch(view.state.tr.insert(view.state.selection.from, schema.nodes.paragraph.create({}))); enter(view.state, view.dispatch, view, false); @@ -346,12 +358,12 @@ export function buildKeymap>(schema: S, props: any): KeyMa const tonode = tx3.selection.$to.node(); if (tx3.selection.to && tx3.doc.nodeAt(tx3.selection.to - 1)) { const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks).setStoredMarks(marks || []); - dispatch(tx4); + dispatch?.(tx4); } - if (view.state.selection.$anchor.depth > 0 && - view.state.selection.$anchor.node(view.state.selection.$anchor.depth-1).type === schema.nodes.list_item && - view.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) { + if ((view?.state.selection.$anchor.depth ??0) > 0 && + view?.state.selection.$anchor.node(view.state.selection.$anchor.depth-1).type === schema.nodes.list_item && + view?.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) { // if text is selected across list items, then we need to forcibly insert a new line since the splitBlock code joins the two list items. enter(view.state, dispatch, view, false); } @@ -368,14 +380,14 @@ export function buildKeymap>(schema: S, props: any): KeyMa // Command to create a blank space bind('Space', () => { - const editDoc = props.TemplateDataDocument ?? props.Document[DocData]; + const editDoc = tbox?._props.TemplateDataDocument ?? tbox?.Document[DocData]; if (editDoc && ![AclAdmin, AclAugment, AclEdit].includes(GetEffectiveAcl(editDoc))) return true; return false; }); - bind('Alt-ArrowUp', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && joinUp(state, dispatch as any)); - bind('Alt-ArrowDown', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && joinDown(state, dispatch as any)); - bind('Mod-BracketLeft', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && lift(state, dispatch as any)); + bind('Alt-ArrowUp', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && joinUp(state, dispatch)); + bind('Alt-ArrowDown', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && joinDown(state, dispatch)); + bind('Mod-BracketLeft', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && lift(state, dispatch)); const cmd = chainCommands(exitCode, (state, dispatch) => { if (dispatch) { diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx index 238267f6e..6dea891a0 100644 --- a/src/client/views/nodes/formattedText/SummaryView.tsx +++ b/src/client/views/nodes/formattedText/SummaryView.tsx @@ -1,12 +1,11 @@ import { TextSelection } from 'prosemirror-state'; -import { Fragment, Node, Slice } from 'prosemirror-model'; +import { Attrs, Fragment, Node, Slice } from 'prosemirror-model'; import * as ReactDOM from 'react-dom/client'; import * as React from 'react'; +import { EditorView } from 'prosemirror-view'; -interface ISummaryView {} // currently nothing needs to be rendered for the internal view of a summary. -// eslint-disable-next-line react/prefer-stateless-function -export class SummaryViewInternal extends React.Component { +export class SummaryViewInternal extends React.Component { render() { return null; } @@ -18,30 +17,30 @@ export class SummaryViewInternal extends React.Component { // method instead of changing prosemirror's text when the expand/elide buttons are clicked. export class SummaryView { dom: HTMLSpanElement; // container for label and value - root: any; + root: ReactDOM.Root; - constructor(node: any, view: any, getPos: any) { + constructor(node: Node, view: EditorView, getPos: () => number | undefined) { this.dom = document.createElement('span'); this.dom.className = this.className(node.attrs.visibility); - this.dom.onpointerdown = (e: any) => { + this.dom.onpointerdown = (e: PointerEvent) => { this.onPointerDown(e, node, view, getPos); }; - this.dom.onkeypress = function (e: any) { + this.dom.onkeypress = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeydown = function (e: any) { + this.dom.onkeydown = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeyup = function (e: any) { + this.dom.onkeyup = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onmousedown = function (e: any) { + this.dom.onmousedown = function (e: MouseEvent) { e.stopPropagation(); }; const js = node.toJSON; - node.toJSON = function (...args: any[]) { - return js.apply(this, args); + node.toJSON = function (...args: unknown[]) { + return js.apply(this, args as []); }; this.root = ReactDOM.createRoot(this.dom); @@ -54,7 +53,7 @@ export class SummaryView { } selectNode() {} - updateSummarizedText(start: any, view: any) { + updateSummarizedText(start: number, view: EditorView) { const mtype = view.state.schema.marks.summarize; const mtypeInc = view.state.schema.marks.summarizeInclusive; let endPos = start; @@ -65,7 +64,7 @@ export class SummaryView { // eslint-disable-next-line no-loop-func view.state.doc.nodesBetween(start, i, (node: Node /* , pos: number, parent: Node, index: number */) => { if (node.isLeaf && !visited.has(node) && !skip) { - if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) { + if (node.marks.find(m => m.type === mtype || m.type === mtypeInc)) { visited.add(node); endPos = i + node.nodeSize - 1; } else skip = true; @@ -75,21 +74,18 @@ export class SummaryView { return TextSelection.create(view.state.doc, start, endPos); } - onPointerDown = (e: any, node: any, view: any, getPos: any) => { + onPointerDown = (e: PointerEvent, node: Node, view: EditorView, getPos: () => number | undefined) => { const visible = !node.attrs.visibility; - const attrs = { ...node.attrs, visibility: visible }; - let textSelection = TextSelection.create(view.state.doc, getPos() + 1); - if (!visible) { - // update summarized text and save in attrs - textSelection = this.updateSummarizedText(getPos() + 1, view); - attrs.text = textSelection.content(); - attrs.textslice = attrs.text.toJSON(); - } + const textSelection = visible // + ? TextSelection.create(view.state.doc, (getPos() ?? 0) + 1) + : this.updateSummarizedText((getPos() ?? 0) + 1, view); // update summarized text and save in attrs + const text = textSelection.content(); + const attrs = { ...node.attrs, visibility: visible, ...(!visible ? { text, textslice: text.toJSON() } : {}) } as Attrs; view.dispatch( view.state.tr .setSelection(textSelection) // select the current summarized text (or where it will be if its collapsed) .replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : node.attrs.text) // collapse/expand it - .setNodeMarkup(getPos(), undefined, attrs) + .setNodeMarkup(getPos() ?? 0, undefined, attrs) ); // update the attrs e.preventDefault(); e.stopPropagation(); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 2142adac8..73c2f5eb8 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -35,7 +35,7 @@ export * from 'pdfjs-dist/build/pdf.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; - Document: Doc; + Doc: Doc; dataDoc: Doc; layoutDoc: Doc; fieldKey: string; @@ -113,8 +113,8 @@ export class PDFViewer extends ObservableReactComponent { () => this._props.layoutDoc._layout_autoHeight, layoutAutoHeight => { if (layoutAutoHeight) { - this._props.layoutDoc._nativeHeight = NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']); - this._props.setHeight?.(NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1)); + this._props.layoutDoc._nativeHeight = NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']); + this._props.setHeight?.(NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1)); } } ); @@ -125,7 +125,7 @@ export class PDFViewer extends ObservableReactComponent { { fireImmediately: true } ); this._disposers.curPage = reaction( - () => Cast(this._props.Document._layout_curPage, 'number', null), + () => Cast(this._props.Doc._layout_curPage, 'number', null), page => page !== undefined && page !== this._pdfViewer?.currentPageNumber && this.gotoPage(page), { fireImmediately: true } ); @@ -181,7 +181,7 @@ export class PDFViewer extends ObservableReactComponent { scrollFocus = (doc: Doc, scrollTop: number, options: FocusViewOptions) => { const mainCont = this._mainCont.current; let focusSpeed: Opt; - if (doc !== this._props.Document && mainCont) { + if (doc !== this._props.Doc && mainCont) { const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); const scrollTo = ClientUtils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight); if (scrollTo !== undefined && scrollTo !== this._props.layoutDoc._layout_scrollTop) { @@ -216,11 +216,11 @@ export class PDFViewer extends ObservableReactComponent { { fireImmediately: true } ); this._disposers.scroll = reaction( - () => Math.abs(NumCast(this._props.Document._layout_scrollTop)), + () => Math.abs(NumCast(this._props.Doc._layout_scrollTop)), pos => { if (!this._ignoreScroll) { this._showWaiting && this.setupPdfJsViewer(); - const viewTrans = quickScroll?.loc ?? StrCast(this._props.Document._viewTransition); + const viewTrans = quickScroll?.loc ?? StrCast(this._props.Doc._viewTransition); const durationMiliStr = viewTrans.match(/([0-9]*)ms/); const durationSecStr = viewTrans.match(/([0-9.]*)s/); const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0; @@ -371,9 +371,9 @@ export class PDFViewer extends ObservableReactComponent { // if alt+left click, drag and annotate this._downX = e.clientX; this._downY = e.clientY; - if ((this._props.Document._freeform_scale || 1) !== 1) return; + if ((this._props.Doc._freeform_scale || 1) !== 1) return; if ((e.button !== 0 || e.altKey) && this._props.isContentActive()) { - this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Document); + this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Doc); } if (!e.altKey && e.button === 0 && this._props.isContentActive() && Doc.ActiveTool !== InkTool.Ink) { this._props.select(false); @@ -433,7 +433,7 @@ export class PDFViewer extends ObservableReactComponent { addDrawingAnnotation = (drawing: Doc) => { // drawing.x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX // const scaleX = this._mainCont.current.offsetWidth / boundingRect.width; - drawing.y = NumCast(drawing.y) + NumCast(this._props.Document.layout_scrollTop); + drawing.y = NumCast(drawing.y) + NumCast(this._props.Doc.layout_scrollTop); this._props.addDocument?.(drawing); }; @@ -478,7 +478,7 @@ export class PDFViewer extends ObservableReactComponent { onClick = (e: React.MouseEvent) => { this._scrollStopper?.(); if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < ClientUtils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < ClientUtils.DRAG_THRESHOLD) { - this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document); + this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Doc); } // e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks }; @@ -506,7 +506,7 @@ export class PDFViewer extends ObservableReactComponent { @computed get annotationLayer() { const inlineAnnos = this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).filter(anno => !anno.hidden); return ( -
+
{inlineAnnos.map(anno => ( ))} @@ -597,7 +597,7 @@ export class PDFViewer extends ObservableReactComponent { onClick={this.onClick} style={{ overflowX: NumCast(this._props.layoutDoc._freeform_scale, 1) !== 1 ? 'scroll' : undefined, - height: !this._props.Document._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Document) : `100%`, + height: !this._props.Doc._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Doc) : `100%`, }}> {this.pdfViewerDiv} {this.annotationLayer} @@ -606,12 +606,12 @@ export class PDFViewer extends ObservableReactComponent { {!this._mainCont.current || !this._annotationLayer.current || !this.props.pdfBox.DocumentView ? null : ( Pdfjs.PixelsPerInch.PDF_TO_CSS_UNITS} - annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)} + annotationLayerScrollTop={NumCast(this._props.Doc._layout_scrollTop)} addDocument={this.addDocumentWrapper} docView={this.props.pdfBox.DocumentView} screenTransform={this.screenToMarqueeXf} diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 8b7e77fba..1f6e80bd1 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -27,7 +27,7 @@ const MAX_ITERATIONS = 25; const ERROR = 0.03; export interface SearchBoxItemProps { - Document: Doc; + Doc: Doc; searchString: string; isLinkSearch: boolean; matchedKeys: string[]; @@ -64,7 +64,7 @@ export class SearchBoxItem extends ObservableReactComponent }); componentWillUnmount(): void { - const doc = this._props.Document; + const doc = this._props.Doc; DocumentView.getFirstDocumentView(doc)?.ComponentView?.search?.('', undefined, true); } @@ -79,23 +79,23 @@ export class SearchBoxItem extends ObservableReactComponent render() { // eslint-disable-next-line no-use-before-define - const formattedType = SearchBox.formatType(StrCast(this._props.Document.type), StrCast(this._props.Document.type_collection)); - const { title } = this._props.Document; + const formattedType = SearchBox.formatType(StrCast(this._props.Doc.type), StrCast(this._props.Doc.type_collection)); + const { title } = this._props.Doc; return ( {title as string}
}>
this.makeLink(this._props.Document) + ? () => this.makeLink(this._props.Doc) : e => { - this.onResultClick(this._props.Document); + this.onResultClick(this._props.Doc); e.stopPropagation(); } } style={{ fontWeight: Doc.Links(this._props.linkFrom).find( - link => Doc.AreProtosEqual(Doc.getOppositeAnchor(link, this._props.linkFrom!), this._props.Document) || Doc.AreProtosEqual(DocCast(Doc.getOppositeAnchor(link, this._props.linkFrom!)?.annotationOn), this._props.Document) + link => Doc.AreProtosEqual(Doc.getOppositeAnchor(link, this._props.linkFrom!), this._props.Doc) || Doc.AreProtosEqual(DocCast(Doc.getOppositeAnchor(link, this._props.linkFrom!)?.annotationOn), this._props.Doc) ) ? 'bold' : '', @@ -449,7 +449,7 @@ export class SearchBox extends ViewBoxBaseComponent() { resultsJSX.push( { this._selectedResult = doc; })} diff --git a/src/client/views/smartdraw/StickerPalette.tsx b/src/client/views/smartdraw/StickerPalette.tsx index 080a05d42..2260d1f73 100644 --- a/src/client/views/smartdraw/StickerPalette.tsx +++ b/src/client/views/smartdraw/StickerPalette.tsx @@ -25,7 +25,7 @@ import { DrawingOptions, SmartDrawHandler } from './SmartDrawHandler'; import './StickerPalette.scss'; interface StickerPaletteProps { - Document: Doc; + Doc: Doc; } enum StickerPaletteMode { @@ -132,7 +132,7 @@ export class StickerPalette extends ObservableReactComponent { this._isLoading = true; - const prevDrawings = DocListCast(this._props.Document.$data); - this._props.Document.$data = undefined; + const prevDrawings = DocListCast(this._props.Doc.$data); + this._props.Doc.$data = undefined; SmartDrawHandler.Instance.AddDrawing = this.addDrawing; this._canInteract = false; Promise.all( @@ -164,7 +164,7 @@ export class StickerPalette extends ObservableReactComponent { this._gptRes.push(gptRes); drawing.$freeform_fitContentsToBox = true; - Doc.AddDocToList(this._props.Document, 'data', drawing); + Doc.AddDocToList(this._props.Doc, 'data', drawing); }; /** @@ -173,8 +173,8 @@ export class StickerPalette extends ObservableReactComponent { - const cIndex = NumCast(this._props.Document.carousel_index); - const focusedDrawing = DocListCast(this._props.Document.data)[cIndex]; + const cIndex = NumCast(this._props.Doc.carousel_index); + const focusedDrawing = DocListCast(this._props.Doc.data)[cIndex]; focusedDrawing.$title = this._opts.text?.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text; focusedDrawing.$ai_drawing_input = this._opts.text; focusedDrawing.$ai_drawing_complexity = this._opts.complexity; @@ -313,7 +313,7 @@ export class StickerPalette extends ObservableReactComponent {this.renderCreateInput()} {this.renderCreateOptions()} - {this.renderDoc(this._props.Document, (r: DocumentView) => { + {this.renderDoc(this._props.Doc, (r: DocumentView) => { this._docCarouselView = r; })}
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts index 42dd0d432..e16073ff4 100644 --- a/src/fields/RichTextUtils.ts +++ b/src/fields/RichTextUtils.ts @@ -20,6 +20,7 @@ import { Doc, Opt } from './Doc'; import { Id } from './FieldSymbols'; import { RichTextField } from './RichTextField'; import { Cast, StrCast } from './Types'; +import { Upload } from '../server/SharedMediaTypes'; export namespace RichTextUtils { const delimiter = '\n'; @@ -127,7 +128,7 @@ export namespace RichTextUtils { return { baseUrl: embeddedObject.imageProperties!.contentUri! }; }); - const uploads = await Networking.PostToServer('/googlePhotosMediaGet', { mediaItems }); + const uploads = (await Networking.PostToServer('/googlePhotosMediaGet', { mediaItems })) as Upload.FileInformation[]; if (uploads.length !== mediaItems.length) { throw new AssertionError({ expected: mediaItems.length, actual: uploads.length, message: 'Error with internally uploading inlineObjects!' }); diff --git a/src/fields/Types.ts b/src/fields/Types.ts index 474882959..af9cb1180 100644 --- a/src/fields/Types.ts +++ b/src/fields/Types.ts @@ -60,16 +60,13 @@ export type CastCtor = ToConstructor | ListSpec; type WithoutList = T extends List ? (R extends RefField ? (R | Promise)[] : R[]) : T; export function Cast(field: FieldResult, ctor: T): FieldResult>; -// eslint-disable-next-line no-redeclare export function Cast(field: FieldResult, ctor: T, defaultVal: WithoutList>> | null): WithoutList>; -// eslint-disable-next-line no-redeclare export function Cast(field: FieldResult, ctor: T, defaultVal?: ToType | null): FieldResult> | undefined { if (field instanceof Promise) { return defaultVal === undefined ? (field.then(f => Cast(f, ctor) as any) as any) : defaultVal === null ? undefined : defaultVal; } if (field !== undefined && !(field instanceof Promise)) { if (typeof ctor === 'string') { - // eslint-disable-next-line valid-typeof if (typeof field === ctor) { return field as ToType; } @@ -140,9 +137,7 @@ export function ImageCastWithSuffix(field: FieldResult, suffix: string, defaultV } export function FieldValue>(field: FieldResult, defaultValue: U): WithoutList; -// eslint-disable-next-line no-redeclare export function FieldValue(field: FieldResult): Opt; -// eslint-disable-next-line no-redeclare export function FieldValue(field: FieldResult, defaultValue?: T): Opt { return field instanceof Promise || field === undefined ? defaultValue : field; } diff --git a/src/server/DashSession/DashSessionAgent.ts b/src/server/DashSession/DashSessionAgent.ts index 891316b80..8688ec049 100644 --- a/src/server/DashSession/DashSessionAgent.ts +++ b/src/server/DashSession/DashSessionAgent.ts @@ -213,9 +213,9 @@ export class DashSessionAgent extends AppliedSessionAgent { // indicate success or failure mainLog(`${error === null ? green('successfully dispatched') : red('failed to dispatch')} ${zipName} to ${cyan(to)}`); error && mainLog(red(error.message)); - } catch (error: any) { + } catch (error: unknown) { mainLog(red('unable to dispatch zipped backup...')); - mainLog(red(error.message)); + mainLog(red((error as { message: string }).message)); } } } -- cgit v1.2.3-70-g09d2 From 29a1fe16297c99ddbed7974b7c602294da9a311d Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 25 Mar 2025 22:40:30 -0400 Subject: fixes to components so that things highlight reasonably in different skins. fixed color picker alternate selection. --- .../components/src/components/Button/Button.scss | 12 +- .../components/src/components/Button/Button.tsx | 345 ++++++++++----------- .../src/components/ColorPicker/ColorPicker.tsx | 44 ++- .../src/components/Dropdown/Dropdown.tsx | 13 +- .../components/DropdownSearch/DropdownSearch.tsx | 190 +++++------- .../src/components/EditableText/EditableText.tsx | 309 +++++++++--------- .../src/components/IconButton/IconButton.scss | 17 +- .../src/components/IconButton/IconButton.tsx | 27 +- .../src/components/ListItem/ListItem.tsx | 2 +- .../src/components/MultiToggle/MultiToggle.tsx | 143 +++++---- .../components/NumberDropdown/NumberDropdown.tsx | 46 ++- .../src/components/NumberInput/NumberInput.tsx | 137 ++++---- packages/components/src/components/Popup/Popup.tsx | 8 +- .../components/src/components/Slider/Slider.tsx | 16 +- .../components/src/components/Toggle/Toggle.tsx | 309 +++++++++--------- packages/components/src/global/globalEnums.tsx | 67 ++-- packages/components/src/global/globalUtils.tsx | 163 +++++----- src/client/util/CalendarManager.tsx | 2 +- src/client/util/GroupManager.tsx | 14 +- src/client/util/SettingsManager.tsx | 28 +- src/client/util/SharingManager.tsx | 4 +- src/client/util/SnappingManager.ts | 54 ++-- src/client/views/StyleProvider.tsx | 4 +- src/client/views/collections/CollectionMenu.tsx | 11 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 36 ++- src/client/views/pdf/GPTPopup/GPTPopup.scss | 4 +- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 46 +-- src/client/views/topbar/TopBar.tsx | 23 +- 28 files changed, 1048 insertions(+), 1026 deletions(-) (limited to 'src/client/util') diff --git a/packages/components/src/components/Button/Button.scss b/packages/components/src/components/Button/Button.scss index bbe2e2470..b2fb48344 100644 --- a/packages/components/src/components/Button/Button.scss +++ b/packages/components/src/components/Button/Button.scss @@ -53,7 +53,7 @@ &.inactive { &:hover { .background { - filter: opacity(0) !important; + filter: opacity(0); } } } @@ -63,13 +63,13 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.5); } } &:hover { .background { - filter: opacity(0.2); + filter: opacity(0.3); } } } @@ -79,7 +79,7 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.2); } } @@ -96,12 +96,12 @@ } .background { - filter: opacity(1) !important; + filter: opacity(1); } &:hover { .background { - filter: brightness(0.8); + filter: opacity(0.3); } } } diff --git a/packages/components/src/components/Button/Button.tsx b/packages/components/src/components/Button/Button.tsx index a91c74a4c..885403640 100644 --- a/packages/components/src/components/Button/Button.tsx +++ b/packages/components/src/components/Button/Button.tsx @@ -1,195 +1,188 @@ -import { Tooltip } from '@mui/material' -import React from 'react' -import { Alignment, IGlobalProps, Placement, Type , getFormLabelSize } from '../../global' -import { Colors, Size } from '../../global/globalEnums' -import { getFontSize, getHeight, isDark } from '../../global/globalUtils' -import { IconButton } from '../IconButton' -import './Button.scss' +import { Tooltip } from '@mui/material'; +import React from 'react'; +import { Alignment, IGlobalProps, Placement, Type, getFormLabelSize } from '../../global'; +import { Colors, Size } from '../../global/globalEnums'; +import { getFontSize, getHeight } from '../../global/globalUtils'; +import { IconButton } from '../IconButton'; +import './Button.scss'; export interface IButtonProps extends IGlobalProps { - onClick?: (event: React.MouseEvent) => void - onDoubleClick?: (event: React.MouseEvent) => void - type?: Type - active?: boolean + onClick?: (event: React.MouseEvent) => void; + onDoubleClick?: (event: React.MouseEvent) => void; + type?: Type; + active?: boolean; - // Content - text?: string - icon?: JSX.Element | string + // Content + text?: string; + icon?: JSX.Element | string; - // Additional stylization - iconPlacement?: Placement - color?: string - colorPicker?: string, - uppercase?: boolean, - align?: Alignment + // Additional stylization + iconPlacement?: Placement; + color?: string; + colorPicker?: string; + uppercase?: boolean; + align?: Alignment; + filter?: string; } export const Button = (props: IButtonProps) => { - const { - text, - icon, - onClick, - onDoubleClick, - onPointerDown, - active, - height, - inactive, - type = Type.PRIM, - label, - uppercase = false, - iconPlacement = 'right', - size = Size.SMALL, - color = Colors.MEDIUM_BLUE, - background, - style, - tooltip, - tooltipPlacement = 'top', - colorPicker, - formLabel, - formLabelPlacement, - fillWidth, - align = fillWidth ? 'flex-start' : 'center' - } = props + const { + text, + icon, + onClick, + onDoubleClick, + onPointerDown, + active, + height, + inactive, + type = Type.PRIM, + filter, + uppercase = false, + iconPlacement = 'right', + size = Size.SMALL, + color = Colors.MEDIUM_BLUE, + background, + style, + tooltip, + tooltipPlacement = 'top', + colorPicker, + formLabel, + formLabelPlacement, + fillWidth, + align = fillWidth ? 'flex-start' : 'center', + } = props; - if (!text) { - return - } - - /** - * Pointer down - * @param e - */ - const handlePointerDown = (e: React.PointerEvent) => { - - if (!inactive && onPointerDown) { - e.stopPropagation(); - e.preventDefault(); - onPointerDown(e) + if (!text) { + return ; } - } - /** - * In the event that there is a single click - * @param e - */ - const handleClick = (e: React.MouseEvent) => { - if (!inactive && onClick) { - e.stopPropagation(); - e.preventDefault(); - onClick(e) - } - } + /** + * Pointer down + * @param e + */ + const handlePointerDown = (e: React.PointerEvent) => { + if (!inactive && onPointerDown) { + e.stopPropagation(); + e.preventDefault(); + onPointerDown(e); + } + }; - /** - * Double click - * @param e - */ - const handleDoubleClick = (e: React.MouseEvent) => { - if (!inactive && onDoubleClick){ - e.stopPropagation(); - e.preventDefault(); - onDoubleClick(e) - } - } + /** + * In the event that there is a single click + * @param e + */ + const handleClick = (e: React.MouseEvent) => { + if (!inactive && onClick) { + e.stopPropagation(); + e.preventDefault(); + onClick(e); + } + }; - const getBorderColor = (): Colors | string | undefined => { - switch(type){ - case Type.PRIM: - return undefined; - case Type.SEC: - if (colorPicker) return colorPicker; - return color; - case Type.TERT: - if (colorPicker) return colorPicker; - if (active) return color; - else return color; - } - } + /** + * Double click + * @param e + */ + const handleDoubleClick = (e: React.MouseEvent) => { + if (!inactive && onDoubleClick) { + e.stopPropagation(); + e.preventDefault(); + onDoubleClick(e); + } + }; - const getColor = (): Colors | string | undefined => { - if (color && background) return color; - switch(type){ - case Type.PRIM: - if (colorPicker) return colorPicker - return color; - case Type.SEC: - if (colorPicker) return colorPicker - return color; - case Type.TERT: - if (colorPicker) { - if (isDark(colorPicker)) return Colors.WHITE; - else return Colors.BLACK + const getBorderColor = (): Colors | string | undefined => { + switch (type) { + case Type.PRIM: + return undefined; + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + return color; } - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK - } - } + }; - const getBackground = (): Colors | string | undefined => { - if (background) return background; - switch(type) { - case Type.PRIM: - if (colorPicker) return colorPicker - return color; - case Type.SEC: - if (colorPicker) return colorPicker - return color; - case Type.TERT: - if (colorPicker) return colorPicker - else return color - } - } + const getColor = (): Colors | string | undefined => { + if (color && background) return color; + switch (type) { + case Type.PRIM: + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + return ''; + } + }; - const defaultProperties: React.CSSProperties = { - height: getHeight(height, size), - minHeight: getHeight(height, size), - width: fillWidth ? '100%' : 'fit-content', - justifyContent: align ? align : undefined, - padding: fillWidth && align === 'center' ? 0 : undefined, - fontWeight: 500, - fontSize: getFontSize(size), - fontFamily: 'sans-serif', - textTransform: uppercase ? 'uppercase' : undefined, - borderColor: getBorderColor(), - color: getColor(), - } + const getBackground = (): Colors | string | undefined => { + if (background) return background; + switch (type) { + case Type.PRIM: + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + } + }; - const backgroundProperties: React.CSSProperties = { - background: getBackground() - } + const defaultProperties: React.CSSProperties = { + height: getHeight(height, size), + minHeight: getHeight(height, size), + width: fillWidth ? '100%' : 'fit-content', + justifyContent: align ? align : undefined, + padding: fillWidth && align === 'center' ? 0 : undefined, + fontWeight: 500, + fontSize: getFontSize(size), + fontFamily: 'sans-serif', + textTransform: uppercase ? 'uppercase' : undefined, + borderColor: getBorderColor(), + color: getColor(), + }; - const button: JSX.Element = ( - -
-
- {iconPlacement == 'left' && icon ?
{icon}
: null} - {text} - {iconPlacement == 'right' && icon ?
{icon}
: null} -
-
-
- - ) + const backgroundProperties: React.CSSProperties = { + background: getBackground(), + filter, + }; - return ( - formLabel ? -
-
{formLabel}
- {button} -
- : - button - ) -} + const button: JSX.Element = ( + +
+
+ {iconPlacement == 'left' && icon ? ( +
+ {icon} +
+ ) : null} + {text} + {iconPlacement == 'right' && icon ? ( +
+ {icon} +
+ ) : null} +
+
+
+ + ); + + return formLabel ? ( +
+
+ {formLabel} +
+ {button} +
+ ) : ( + button + ); +}; diff --git a/packages/components/src/components/ColorPicker/ColorPicker.tsx b/packages/components/src/components/ColorPicker/ColorPicker.tsx index 632b470f0..72e02d955 100644 --- a/packages/components/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/components/src/components/ColorPicker/ColorPicker.tsx @@ -1,5 +1,5 @@ import React, { useRef, useState } from 'react'; -import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker } from 'react-color'; +import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker, ColorResult } from 'react-color'; import { IGlobalProps, Size, Type, getFormLabelSize } from '../../global'; import { Button } from '../Button'; import { IconButton } from '../IconButton'; @@ -16,12 +16,12 @@ export interface IColorPickerProps extends IGlobalProps { colorPickerType?: ColorPickerType; defaultPickerType?: ColorPickerType; selectedColor?: string; - setSelectedColor: (color: any) => unknown; - setFinalColor: (color: any) => unknown; + setSelectedColor: (color: string) => unknown; + setFinalColor: (color: string) => unknown; } export const ColorPicker = (props: IColorPickerProps) => { - const [selectedColorLoc, setSelectedColorLoc] = useState(); + const [selectedColorLoc, setSelectedColorLoc] = useState(); const { defaultPickerType, text, @@ -31,6 +31,7 @@ export const ColorPicker = (props: IColorPickerProps) => { size = Size.SMALL, type = Type.TERT, icon, + background, selectedColor = selectedColorLoc, setSelectedColor = setSelectedColorLoc, setFinalColor = setSelectedColorLoc, @@ -40,32 +41,25 @@ export const ColorPicker = (props: IColorPickerProps) => { } = props; const [isOpen, setOpen] = useState(false); const [pickerSelectorOpen, setPickerSelectorOpen] = useState(false); - const decimalToHexString = (number: number) => { + const decimalToHexString = (numberIn: number) => { + let number = numberIn; if (number < 0) { number = 0xffffffff + number + 1; } return (number < 16 ? '0' : '') + number.toString(16).toUpperCase(); }; - const colorString = (color: any) => { - return color.hex === 'transparent' ? color.hex : color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff'); - }; - const onChange = (color: any) => { - setSelectedColor(colorString(color) as any); - }; - const onChangeComplete = (color: any) => { - setFinalColor(colorString(color) as any); - }; + const colorString = (c: ColorResult) => (c.hex === 'transparent' ? c.hex : c.hex + (c.rgb.a ? decimalToHexString(Math.round(c.rgb.a * 255)) : 'ff')); + const onChange = (c: ColorResult) => setSelectedColor(colorString(c)); + const onChangeComplete = (c: ColorResult) => setFinalColor(colorString(c)); const [picker, setPicker] = useState(defaultPickerType ?? 'Classic'); const toggleRef = useRef(null); const getToggle = () => (
- {icon && !text ? ( - - ) : text ? ( -
); @@ -92,14 +86,12 @@ export const ColorPicker = (props: IColorPickerProps) => { ); } // prettier-ignore }; - const openChanged = (isOpen: boolean) => setPickerSelectorOpen(isOpen); + const openChanged = (state: boolean) => setPickerSelectorOpen(state); const getPopup = (): JSX.Element => { if (colorPickerType) { return getColorPicker(colorPickerType); } else { - // Todo: this would be much easier if the selectedColor was a Color, not a string. - const newColor = selectedColor === 'transparent' ? 'white' : selectedColor?.startsWith('#') ? selectedColor.substring(0, 7) : selectedColor?.startsWith('rgba') ? selectedColor?.replace(/,[0-9]*\)/, '1)') : selectedColor; return (
{ val: item, }; })} + background={background} activeChanged={openChanged} placement={'right'} - color={newColor} + color={color} type={Type.PRIM} dropdownType={DropdownType.SELECT} selectedVal={picker} @@ -126,7 +119,7 @@ export const ColorPicker = (props: IColorPickerProps) => { const popupContainsPt = (x: number, y: number) => { const rect = toggleRef.current?.getBoundingClientRect(); - return rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y; + return pickerSelectorOpen || (rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y) ? true : false; }; const colorPicker: JSX.Element = ( @@ -138,6 +131,7 @@ export const ColorPicker = (props: IColorPickerProps) => { tooltip={tooltip} size={size} color={selectedColor} + background={background} popup={getPopup()} popupContainsPt={popupContainsPt} // this should prohbably test to see if the click pt is actually within the picker selector list popup. /> @@ -145,7 +139,7 @@ export const ColorPicker = (props: IColorPickerProps) => { return formLabel ? (
-
+
{formLabel}
{colorPicker} diff --git a/packages/components/src/components/Dropdown/Dropdown.tsx b/packages/components/src/components/Dropdown/Dropdown.tsx index b9b6f01b8..783c7daa4 100644 --- a/packages/components/src/components/Dropdown/Dropdown.tsx +++ b/packages/components/src/components/Dropdown/Dropdown.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { FaCaretDown, FaCaretLeft, FaCaretRight, FaCaretUp } from 'react-icons/fa'; import { Popup, PopupTrigger } from '..'; -import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global'; +import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, getFormLabelSize } from '../../global'; import { IconButton } from '../IconButton'; import { ListBox } from '../ListBox'; import { IListItemProps, ListItem } from '../ListItem'; @@ -92,7 +92,7 @@ export const Dropdown = (props: IDropdownProps) => { textTransform: uppercase ? 'uppercase' : undefined, borderColor: getBorderColor(), background, - color: color && background ? color : type == Type.TERT ? (isDark(color) ? Colors.WHITE : Colors.BLACK) : color, + color: color, }; const backgroundProperties: React.CSSProperties = { @@ -116,9 +116,9 @@ export const Dropdown = (props: IDropdownProps) => {
{selectedVal && }
- +
-
+
); case DropdownType.CLICK: @@ -127,9 +127,9 @@ export const Dropdown = (props: IDropdownProps) => {
- +
-
+
); } @@ -157,6 +157,7 @@ export const Dropdown = (props: IDropdownProps) => { size={size} fillWidth={true} color={color} + background={background} popup={ { - const { - size, - height, - maxItems, - items, - dropdownSearchType, - selectedVal, - // setSelectedVal, - tooltip, - title = "DropdownSearch", - type, - width, - color - } = props + const { size, height, maxItems, items, dropdownSearchType, type, width, color } = props; - // const [selectedItem, setSelectedItem] = useState< - // IListItemProps | undefined - // >(selectedVal) + // const [selectedItem, setSelectedItem] = useState< + // IListItemProps | undefined + // >(selectedVal) - const [searchTerm, setSearchTerm] = useState(undefined) - const [isEditing, setIsEditing] = useState(false) - const [active, setActive] = useState(false) + const [searchTerm, setSearchTerm] = useState(undefined); + const [isEditing, setIsEditing] = useState(false); + const [active, setActive] = useState(false); - const getToggle = () => { - switch (dropdownSearchType) { - case DropdownSearchType.SELECT: - return (
{ - e.stopPropagation() - !isEditing && setIsEditing(true) - }} - > - {/* {selectedItem && !isEditing ? ( + const getToggle = () => { + switch (dropdownSearchType) { + case DropdownSearchType.SELECT: + return ( +
{ + e.stopPropagation(); + !isEditing && setIsEditing(true); + }}> + {/* {selectedItem && !isEditing ? ( ) : ( */} -
- { - // setSearchTerm(val) - // }} - size={Size.SMALL} - setEditing={setIsEditing} - /> -
- {/* )} */} -
- } - inactive - /> -
-
-
); - case DropdownSearchType.CLICK: - default: - return ( -
-
- ) - } - } +
+ { + // setSearchTerm(val) + // }} + size={Size.SMALL} + setEditing={setIsEditing} + /> +
+ {/* )} */} +
+ } inactive /> +
+
+
+ ); + case DropdownSearchType.CLICK: + default: + return
; + } + }; - return ( -
- - } - /> -
- ) -} + return ( +
+ + } + /> +
+ ); +}; diff --git a/packages/components/src/components/EditableText/EditableText.tsx b/packages/components/src/components/EditableText/EditableText.tsx index c361cf183..56cbc064d 100644 --- a/packages/components/src/components/EditableText/EditableText.tsx +++ b/packages/components/src/components/EditableText/EditableText.tsx @@ -1,21 +1,21 @@ -import React, { useState } from 'react' -import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global' -import './EditableText.scss' -import { Toggle, ToggleType } from '../Toggle' -import { FaEye, FaEyeSlash} from 'react-icons/fa' +import React, { useState } from 'react'; +import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global'; +import './EditableText.scss'; +import { Toggle, ToggleType } from '../Toggle'; +import { FaEye, FaEyeSlash } from 'react-icons/fa'; export interface IEditableTextProps extends IGlobalProps { - val?: string | number - setVal?: (newText: string | number) => unknown - onEnter?: (newText: string | number) => unknown - setEditing?: (bool: boolean) => unknown - placeholder?: string - editing?: boolean - size?: Size - height?: number - multiline?: boolean - textAlign?: TextAlignment - password?: boolean + val?: string | number; + setVal?: (newText: string | number) => unknown; + onEnter?: (newText: string | number) => unknown; + setEditing?: (bool: boolean) => unknown; + placeholder?: string; + editing?: boolean; + size?: Size; + height?: number; + multiline?: boolean; + textAlign?: TextAlignment; + password?: boolean; } /** @@ -25,152 +25,149 @@ export interface IEditableTextProps extends IGlobalProps { * @returns */ export const EditableText = (props: IEditableTextProps) => { - const [valLoc, setValLoc] = useState('') - const [editingLoc, setEditingLoc] = useState(false) - const { - height, - size, - val = valLoc, - setVal = setValLoc, - onEnter, - setEditing = setEditingLoc, - color = Colors.MEDIUM_BLUE, - background, - type = Type.PRIM, - placeholder, - width, - multiline, - textAlign = 'left', - formLabel, - formLabelPlacement, - fillWidth, - password, - editing = password ? true : editingLoc, - style - } = props - const [showPassword, setShowPassword] = useState(false) + const [valLoc, setValLoc] = useState(''); + const [editingLoc, setEditingLoc] = useState(false); + const { + height, + size, + val = valLoc, + setVal = setValLoc, + onEnter, + setEditing = setEditingLoc, + color = Colors.MEDIUM_BLUE, + background, + type = Type.PRIM, + placeholder, + width, + textAlign = 'left', + formLabel, + formLabelPlacement, + fillWidth, + password, + editing = password ? true : editingLoc, + style, + } = props; + const [showPassword, setShowPassword] = useState(false); - const handleOnChange = (event: React.ChangeEvent) => { - setVal(event.target.value) - } - const handleKeyPress = (event: React.KeyboardEvent) => { - if (event.key === 'Enter') { - onEnter?.((event.target as HTMLInputElement).value) - } - } + const handleOnChange = (event: React.ChangeEvent) => { + setVal(event.target.value); + }; + const handleKeyPress = (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + onEnter?.((event.target as HTMLInputElement).value); + } + }; - const getBorderColor = (): Colors | string | undefined => { - switch(type){ - case Type.PRIM: - return undefined; - case Type.SEC: - return color; - case Type.TERT: - if (editing) return color; - else return color; - } - } + const getBorderColor = (): Colors | string | undefined => { + switch (type) { + case Type.PRIM: + return undefined; + case Type.SEC: + return color; + case Type.TERT: + if (editing) return color; + else return color; + } + }; - const getColor = (): Colors | string | undefined => { - if (color && background) return color; - switch(type){ - case Type.PRIM: - return color; - case Type.SEC: - return color; - case Type.TERT: - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK - } - } + const getColor = (): Colors | string | undefined => { + if (color && background) return color; + switch (type) { + case Type.PRIM: + return color; + case Type.SEC: + return color; + case Type.TERT: + if (isDark(color)) return Colors.WHITE; + else return Colors.BLACK; + } + }; - const getBackground = (): Colors | string | undefined => { - if (background) return background; - switch(type){ - case Type.PRIM: - return color; - case Type.SEC: - return color; - case Type.TERT: - return color - } - } + const getBackground = (): Colors | string | undefined => { + if (background) return background; + switch (type) { + case Type.PRIM: + return color; + case Type.SEC: + return color; + case Type.TERT: + return color; + } + }; - const defaultProperties: React.CSSProperties = { - height: getHeight(height, size), - minHeight: getHeight(height, size), - width: fillWidth ? '100%' : width, - padding: undefined, - fontWeight: 500, - fontSize: getFontSize(size), - fontFamily: 'sans-serif', - borderColor: getBorderColor(), - color: getColor() - } + const defaultProperties: React.CSSProperties = { + height: getHeight(height, size), + minHeight: getHeight(height, size), + width: fillWidth ? '100%' : width, + padding: undefined, + fontWeight: 500, + fontSize: getFontSize(size), + fontFamily: 'sans-serif', + borderColor: getBorderColor(), + color: getColor(), + }; - const backgroundProperties: React.CSSProperties = { - background: getBackground() - } + const backgroundProperties: React.CSSProperties = { + background: getBackground(), + }; - const editableText: JSX.Element = ( -
setEditing(true)} - > - {editing ? ( - { - !password && setEditing(false) - }} - defaultValue={val} - > - ) : ( -
- {val ? val : placeholder} + const editableText: JSX.Element = ( +
setEditing(true)}> + {editing ? ( + { + !password && setEditing(false); + }} + defaultValue={val}> + ) : ( +
+ {val ? val : placeholder} +
+ )} + {password && ( +
+ setShowPassword(!showPassword)} + tooltip={`${showPassword ? 'Hide' : 'Show'} Password`} + icon={} + iconFalse={} + /> +
+ )} +
- )} - {password &&
- setShowPassword(!showPassword)} - tooltip={`${showPassword ? 'Hide' : 'Show'} Password`} - icon={} - iconFalse={} - /> -
} -
-
- ) + ); -return ( - formLabel ? -
-
{formLabel}
- {editableText} -
- : - editableText - ) -} + return formLabel ? ( +
+
+ {formLabel} +
+ {editableText} +
+ ) : ( + editableText + ); +}; diff --git a/packages/components/src/components/IconButton/IconButton.scss b/packages/components/src/components/IconButton/IconButton.scss index f899dc50f..3f0dd26ea 100644 --- a/packages/components/src/components/IconButton/IconButton.scss +++ b/packages/components/src/components/IconButton/IconButton.scss @@ -45,7 +45,7 @@ &.inactive { .background { - filter: opacity(0) !important; + filter: opacity(0); } } @@ -54,13 +54,13 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.5); } } &:hover { .background { - filter: opacity(0.2); + filter: opacity(0.3); } } } @@ -70,7 +70,7 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.2); } } @@ -85,10 +85,17 @@ &:hover { box-shadow: global.$standard-button-shadow; } + .background { + filter: opacity(0); + + &.active { + filter: opacity(0.5); + } + } &:hover { .background { - filter: brightness(0.8); + filter: opacity(0.3); } } } diff --git a/packages/components/src/components/IconButton/IconButton.tsx b/packages/components/src/components/IconButton/IconButton.tsx index 048048b20..f61f589b9 100644 --- a/packages/components/src/components/IconButton/IconButton.tsx +++ b/packages/components/src/components/IconButton/IconButton.tsx @@ -1,6 +1,6 @@ import { Tooltip } from '@mui/material'; import React from 'react'; -import { Colors, Size, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global'; +import { Colors, Size, Type, getFontSize, getHeight, getFormLabelSize } from '../../global'; import { IButtonProps } from '../Button'; import './IconButton.scss'; @@ -15,6 +15,7 @@ export const IconButton = (props: IButtonProps) => { type = Type.PRIM, color = Colors.MEDIUM_BLUE, background, + filter, label, height, size = Size.SMALL, @@ -71,6 +72,7 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: + return ''; if (colorPicker) return colorPicker; if (active) return color; else return color; @@ -85,12 +87,7 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: - if (colorPicker) { - if (isDark(colorPicker)) return Colors.WHITE; - else return Colors.BLACK; - } - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK; + return ''; } }; @@ -102,15 +99,14 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: - if (colorPicker) return colorPicker; - else return color; + return ''; //color; } }; const defaultProperties: React.CSSProperties = { - height: getHeight(+(height ?? 0), size), - width: fillWidth ? '100%' : getHeight(+(height ?? 0), size), - minWidth: getHeight(+(height ?? 0), size), + height: getHeight(height, size), + width: fillWidth ? '100%' : getHeight(height, size), + minWidth: getHeight(height, size), fontWeight: 500, fontSize: getFontSize(size, true), borderColor: getBorderColor(), @@ -119,6 +115,7 @@ export const IconButton = (props: IButtonProps) => { const backgroundProperties: React.CSSProperties = { background: getBackground(), + filter, }; const iconButton: JSX.Element = ( @@ -126,9 +123,9 @@ export const IconButton = (props: IButtonProps) => {
{icon} - {colorPicker && type !== Type.TERT &&
} + {colorPicker &&
} {label && !hideLabel && ( -
+
{label}
)} @@ -140,7 +137,7 @@ export const IconButton = (props: IButtonProps) => { return formLabel ? (
-
+
{formLabel}
{iconButton} diff --git a/packages/components/src/components/ListItem/ListItem.tsx b/packages/components/src/components/ListItem/ListItem.tsx index e04c6fbee..6bb3e3824 100644 --- a/packages/components/src/components/ListItem/ListItem.tsx +++ b/packages/components/src/components/ListItem/ListItem.tsx @@ -85,7 +85,7 @@ export const ListItem = (props: IListItemProps) => {
diff --git a/packages/components/src/components/MultiToggle/MultiToggle.tsx b/packages/components/src/components/MultiToggle/MultiToggle.tsx index 7fff12c8e..0f659c5ca 100644 --- a/packages/components/src/components/MultiToggle/MultiToggle.tsx +++ b/packages/components/src/components/MultiToggle/MultiToggle.tsx @@ -1,29 +1,29 @@ -import * as React from 'react' -import { useState } from 'react' -import { Colors, IGlobalProps, Type } from '../../global' -import { Group } from '../Group' -import { IconButton } from '../IconButton' -import { Popup } from '../Popup' -import { IToggleProps, Toggle, ToggleType } from '../Toggle' +import * as React from 'react'; +import { useState } from 'react'; +import { Colors, IGlobalProps, Type } from '../../global'; +import { Group } from '../Group'; +import { IconButton } from '../IconButton'; +import { Popup } from '../Popup'; +import { IToggleProps, Toggle, ToggleType } from '../Toggle'; export interface IToggleItemProps extends IToggleProps { - val: string + val: string; } export interface IMultiToggleProps extends IGlobalProps { - items: IToggleItemProps[] + items: IToggleItemProps[]; multiSelect?: boolean; - defaultSelectedItems?: (string|number) | ((string|number)[]), - selectedItems?: (string | number) | ((string|number)[]), - onSelectionChange?: (val: (string|number) | (string|number)[], added: boolean) => unknown, + defaultSelectedItems?: (string | number) | (string | number)[]; + selectedItems?: (string | number) | (string | number)[]; + onSelectionChange?: (val: (string | number) | (string | number)[], added: boolean) => unknown; isToggle?: boolean; toggleStatus?: boolean; } -function promoteToArrayOrUndefined(d : (string|number)[]|(string|number)|undefined) { - return d instanceof Array || d === undefined ? d: [d]; +function promoteToArrayOrUndefined(d: (string | number)[] | (string | number) | undefined) { + return d instanceof Array || d === undefined ? d : [d]; } -function promoteToArray(d : (string|number)[]|(string|number)|undefined) { +function promoteToArray(d: (string | number)[] | (string | number) | undefined) { return promoteToArrayOrUndefined(d) ?? []; } @@ -32,56 +32,67 @@ export const MultiToggle = (props: IMultiToggleProps) => { const initVal = (!init ? undefined : promoteToArrayOrUndefined(props.defaultSelectedItems)) ?? promoteToArrayOrUndefined(props.selectedItems) ?? []; init = false; - const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string|number) | ((string|number)[])); + const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string | number) | (string | number)[]); const { items, selectedItems = selectedItemsLocal, tooltip, tooltipPlacement = 'top', onSelectionChange, color, background } = props; const itemsMap = new Map(); - items.forEach((item) => itemsMap.set(item.val, item)); - return
- - - {promoteToArray(selectedItems).length < 2 ? null : -
- + -
} -
} - isToggle={props.isToggle} - toggleFunc={() => { - const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); - selItem && setSelectedItemsLocal([selItem.val]); - }} - type={props.type} - label={props.isToggle ? props.label : undefined} - toggleStatus={props.isToggle ? props.toggleStatus : undefined} - color={color} - popup={ - {items.map((item, i) => - { - const selected = new Set(); - promoteToArray(selectedItems).forEach(val => val && selected.add(val)); - const toAdd = !props.multiSelect || !selected.has(item.val) - if (!toAdd) selected.delete(item.val); - else item.val && selected.add(item.val); - onSelectionChange?.(item.val, toAdd); - setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val); - e.stopPropagation(); - }}/> - )} - } - /> -
-} \ No newline at end of file + items.forEach(item => itemsMap.set(item.val, item)); + return ( +
+ + + {promoteToArray(selectedItems).length < 2 ? null :
+
} +
+ ) + } + isToggle={props.isToggle} + toggleFunc={() => { + const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); + selItem && setSelectedItemsLocal([selItem.val]); + }} + type={props.type} + label={props.isToggle ? props.label : undefined} + toggleStatus={props.isToggle ? props.toggleStatus : undefined} + color={color} + background={background} + popup={ + + {items.map((item, i) => ( + { + const selected = new Set(); + promoteToArray(selectedItems).forEach(val => val && selected.add(val)); + const toAdd = !props.multiSelect || !selected.has(item.val); + if (!toAdd) selected.delete(item.val); + else item.val && selected.add(item.val); + onSelectionChange?.(item.val, toAdd); + setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val); + e.stopPropagation(); + }} + /> + ))} + + } + /> +
+ ); +}; diff --git a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx index 7f12198d5..b5f55bacf 100644 --- a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx +++ b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx @@ -20,11 +20,41 @@ export interface INumberDropdownProps extends INumberProps { export const NumberDropdown = (props: INumberDropdownProps) => { const [numberLoc, setNumberLoc] = useState(0); - const { fillWidth, numberDropdownType = false, color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel, tooltip } = props; + const { + fillWidth, // + numberDropdownType = false, + color = Colors.MEDIUM_BLUE, + type, + formLabelPlacement, + showPlusMinus, + min, + max, + unit, + background, + step = 1, + number = numberLoc, + setNumber = setNumberLoc, + size, + formLabel, + tooltip, + } = props; const [isOpen, setOpen] = useState(false); let toggleText = number.toString(); if (unit) toggleText = toggleText + unit; - let toggle = setOpen(!isOpen)} />; + let toggle = ( + setOpen(!isOpen)} + /> + ); if (showPlusMinus) { toggle = ( @@ -75,23 +105,23 @@ export const NumberDropdown = (props: INumberDropdownProps) => { break; case 'slider': default: - popup = ; + popup = ; break; case 'input': - popup = ; + popup = ; break; } const numberDropdown: JSX.Element = ( -
- +
+
); return formLabel ? ( -
+
{numberDropdown} -
+
setOpen(!isOpen)} style={{ cursor: 'pointer', height: '25%', fontSize: getFormLabelSize(size) }}> {formLabel}
diff --git a/packages/components/src/components/NumberInput/NumberInput.tsx b/packages/components/src/components/NumberInput/NumberInput.tsx index 33573d000..56c61a41e 100644 --- a/packages/components/src/components/NumberInput/NumberInput.tsx +++ b/packages/components/src/components/NumberInput/NumberInput.tsx @@ -1,89 +1,76 @@ -import * as React from 'react' -import { Colors, INumberProps , Type, getFormLabelSize, getHeight } from '../../global' -import './NumberInput.scss' -import { useState } from 'react' -import { Group } from '../Group' -import { Toggle, ToggleType } from '../Toggle' -import { IconButton } from '../IconButton' -import * as fa from 'react-icons/fa' -import { EditableText } from '../EditableText' +import * as React from 'react'; +import { Colors, INumberProps, getFormLabelSize, getHeight } from '../../global'; +import './NumberInput.scss'; +import { useState } from 'react'; +import { Group } from '../Group'; +import { IconButton } from '../IconButton'; +import * as fa from 'react-icons/fa'; +import { EditableText } from '../EditableText'; export interface INumberInputProps extends INumberProps { - showPlusMinus?: boolean + showPlusMinus?: boolean; } export const NumberInput = (props: INumberInputProps) => { - const [numberLoc, setNumberLoc] = useState(10) - const { - color = Colors.MEDIUM_BLUE, - type, - formLabelPlacement, - showPlusMinus, - min, - max, - unit = '', - width, - fillWidth = width ? true : false, - step = 1, - number = numberLoc, - setNumber = setNumberLoc, - size, - formLabel, - tooltip } = - props; + const [numberLoc, setNumberLoc] = useState(10); + const { color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit = '', width, fillWidth = width ? true : false, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel } = props; + + let input = ( + setNumber(!isNaN(Number(val)) ? Number(val) : number)} + /> + ); - let input = setNumber(!isNaN(Number(val)) ? Number(val) : number)} - />; - if (showPlusMinus) { - input = - {input} - } - color={color} - onClick={(e) => { - e.stopPropagation(); - setNumber(number - step); - }} - inactive={number - step < min} - tooltip={`Subtract ${step}${unit}`} - /> - } - color={color} - onClick={(e) => { - e.stopPropagation(); - setNumber(number + step); - }} - inactive={number + step > max} - tooltip={`Add ${step}${unit}`} - /> - + input = ( + + {input} + } + color={color} + onClick={e => { + e.stopPropagation(); + setNumber(number - step); + }} + inactive={number - step < min} + tooltip={`Subtract ${step}${unit}`} + /> + } + color={color} + onClick={e => { + e.stopPropagation(); + setNumber(number + step); + }} + inactive={number + step > max} + tooltip={`Add ${step}${unit}`} + /> + + ); } - - return ( - formLabel ? -
-
{formLabel}
-
+ return formLabel ? ( +
+
+ {formLabel} +
+
{input}
- : -
+ ) : ( +
{input}
- ) -} \ No newline at end of file + ); +}; diff --git a/packages/components/src/components/Popup/Popup.tsx b/packages/components/src/components/Popup/Popup.tsx index 5a58fee29..82e60f343 100644 --- a/packages/components/src/components/Popup/Popup.tsx +++ b/packages/components/src/components/Popup/Popup.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; -import { Colors, IGlobalProps, Placement, Size, isDark } from '../../global'; +import { IGlobalProps, Placement, Size } from '../../global'; import { Toggle, ToggleType } from '../Toggle'; import './Popup.scss'; import { Popper } from '@mui/material'; @@ -57,7 +57,7 @@ export const Popup = (props: IPopupProps) => { height, fillWidth, iconPlacement = 'left', - background = isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, + background, popupContainsPt, } = props; @@ -116,7 +116,7 @@ export const Popup = (props: IPopupProps) => { size={size} type={type} color={color} - background={props.isToggle ? undefined : background} + background={background} toggleType={ToggleType.BUTTON} icon={icon} iconPlacement={iconPlacement} @@ -138,7 +138,7 @@ export const Popup = (props: IPopupProps) => {
{ const toDecimal = (num: number) => (decimals !== undefined ? Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals) : num); const getLeftPos = (locVal: number) => { - const dragger = getHeight(+(height || 0), size); + const dragger = +getHeight(height, size); return ((locVal - min) / (max - min)) * (width - dragger); }; @@ -65,8 +65,8 @@ export const Slider = (props: ISliderProps) => { background: color, color: isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontSize: getFontSize(size), - height: getHeight(+(height || 0), size), - width: getHeight(+(height || 0), size), + height: getHeight(height, size), + width: getHeight(height, size), top: 0, }}> {toDecimal(locVal)} @@ -132,7 +132,7 @@ export const Slider = (props: ISliderProps) => { lastEndVal = endNumberLoc; }} style={{ - padding: `5px 0px ${getHeight(+(height || 0), size)}px 0px`, + padding: `5px 0px ${getHeight(height, size)}px 0px`, width: fillWidth ? '100%' : 'fit-content', }}>
{ r && new ResizeObserver(() => setWidth(+(r?.clientWidth ?? 100))).observe(r); setWidth(+(r?.clientWidth ?? 100)); }} - style={{ height: getHeight(+(height || 0), size) }} + style={{ height: getHeight(height, size) }} onPointerDown={onPointerDown}> {ValSlider}
selected, false -> unselected - toggleType?: ToggleType - iconFalse?: JSX.Element | string + toggleStatus?: boolean; // true -> selected, false -> unselected + toggleType?: ToggleType; + iconFalse?: JSX.Element | string; + triState?: boolean; } export const Toggle = (props: IToggleProps) => { - const [toggleStatusLoc, setToggleStatusLoc] = useState(true); - const { - toggleStatus = toggleStatusLoc, - toggleType = ToggleType.CHECKBOX, - type = Type.SEC, - style, - color, - background, - text, - icon, - iconFalse = icon, - height, - inactive, - label, - iconPlacement, - onPointerDown, - onClick, - tooltip, - tooltipPlacement = 'top', - size = Size.SMALL, - formLabel, - formLabelPlacement, - fillWidth, - align - } = props + const [toggleStatusLoc, setToggleStatusLoc] = useState(true); + const { + toggleStatus = toggleStatusLoc, + toggleType = ToggleType.CHECKBOX, + type = Type.SEC, + color, + background, + text, + icon, + iconFalse = icon, + height, + inactive, + label, + iconPlacement, + onPointerDown, + onClick, + triState, + tooltip, + tooltipPlacement = 'top', + size = Size.SMALL, + formLabel, + formLabelPlacement, + fillWidth, + align, + } = props; - /** - * Pointer down - * @param e - */ - const handlePointerDown = (e: React.PointerEvent) => { - if (!inactive && onPointerDown){ - e.stopPropagation(); - e.preventDefault(); - onPointerDown(e) - } - } + /** + * Pointer down + * @param e + */ + const handlePointerDown = (e: React.PointerEvent) => { + if (!inactive && onPointerDown) { + e.stopPropagation(); + e.preventDefault(); + onPointerDown(e); + } + }; - /** - * Single click - * @param e - */ - const handleClick = (e: React.MouseEvent) => { - if (toggleStatus === toggleStatusLoc) { - setToggleStatusLoc(!toggleStatus) - } - - if (!inactive && onClick) { - e.stopPropagation(); - e.preventDefault(); - onClick(e); - } - } + /** + * Single click + * @param e + */ + const handleClick = (e: React.MouseEvent) => { + if (toggleStatus === toggleStatusLoc) { + setToggleStatusLoc(!toggleStatus); + } - const defaultProperties = { - height: getHeight(height, size), - borderColor: color - } + if (!inactive && onClick) { + e.stopPropagation(); + e.preventDefault(); + onClick(e); + } + }; - let toggleElement: JSX.Element; + const defaultProperties = { + height: getHeight(height, size), + borderColor: color, + }; - switch(toggleType) { - case ToggleType.BUTTON: - toggleElement = ( -