diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/ComparisonBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DataVizBox/DataVizBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 96 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 120 | ||||
| -rw-r--r-- | src/client/views/nodes/EquationBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValuePair.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/nodes/LinkBox.tsx | 5 | ||||
| -rw-r--r-- | src/client/views/nodes/MapBox/MapBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/RecordingBox/RecordingBox.tsx | 13 | ||||
| -rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 31 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 35 | ||||
| -rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 21 |
15 files changed, 136 insertions, 212 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 685a5aca4..62c4cc61a 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -296,9 +296,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF <div style={{ position: 'absolute', width: this.PanelWidth(), height: this.PanelHeight(), background: 'lightGreen' }} /> ) : ( <DocumentView - parent={this} // eslint-disable-next-line react/jsx-props-no-spreading {...OmitKeys(this._props,this.WrapperKeys.map(val => val.lower)).omit} // prettier-ignore + parent={this} DataTransition={this.DataTransition} LocalRotation={this.localRotation} CollectionFreeFormDocumentView={this.returnThis} diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 474d54119..e1d16549c 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -13,7 +13,7 @@ import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { dropActionType } from '../../util/DropActionTypes'; import { undoBatch } from '../../util/UndoManager'; -import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; +import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { PinDocView, PinProps } from '../PinFuncs'; import { StyleProp } from '../StyleProp'; import './ComparisonBox.scss'; diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 15187b4e4..9ca63194c 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -18,7 +18,7 @@ import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { UndoManager, undoable } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; -import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent'; +import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { MarqueeAnnotator } from '../../MarqueeAnnotator'; import { PinProps } from '../../PinFuncs'; import { SidebarAnnos } from '../../SidebarAnnos'; @@ -41,7 +41,7 @@ export enum DataVizView { } @observer -export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface { +export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { private _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); private _marqueeref = React.createRef<MarqueeAnnotator>(); private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef(); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index ec9db8480..18529a429 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -2,7 +2,6 @@ import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import JsxParser from 'react-jsx-parser'; import * as XRegExp from 'xregexp'; import { OmitKeys } from '../../../ClientUtils'; import { Without, emptyPath } from '../../../Utils'; @@ -11,56 +10,15 @@ import { AclPrivate, DocData } from '../../../fields/DocSymbols'; import { ScriptField } from '../../../fields/ScriptField'; import { Cast, DocCast, StrCast } from '../../../fields/Types'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; -import { InkingStroke } from '../InkingStroke'; -import { ObservableReactComponent } from '../ObservableReactComponent'; -import { CollectionCalendarView } from '../collections/CollectionCalendarView'; -import { CollectionDockingView } from '../collections/CollectionDockingView'; -import { CollectionView } from '../collections/CollectionView'; -import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; -import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView'; -import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox'; -import { SearchBox } from '../search/SearchBox'; -import { AudioBox } from './AudioBox'; -import { ComparisonBox } from './ComparisonBox'; -import { DataVizBox } from './DataVizBox/DataVizBox'; +import { ObservableReactComponent, ObserverJsxParser } from '../ObservableReactComponent'; import './DocumentView.scss'; -import { EquationBox } from './EquationBox'; -import { FieldView, FieldViewProps } from './FieldView'; -import { FontIconBox } from './FontIconBox/FontIconBox'; -import { FunctionPlotBox } from './FunctionPlotBox'; -import { ImageBox } from './ImageBox'; -import { KeyValueBox } from './KeyValueBox'; -import { LabelBox } from './LabelBox'; -import { LinkBox } from './LinkBox'; -import { LoadingBox } from './LoadingBox'; -import { MapBox } from './MapBox/MapBox'; -import { MapPushpinBox } from './MapBox/MapPushpinBox'; -import { PDFBox } from './PDFBox'; -import { PhysicsSimulationBox } from './PhysicsBox/PhysicsSimulationBox'; -import { RecordingBox } from './RecordingBox'; -import { ScreenshotBox } from './ScreenshotBox'; -import { ScriptingBox } from './ScriptingBox'; -import { VideoBox } from './VideoBox'; -import { WebBox } from './WebBox'; -import { FormattedTextBox } from './formattedText/FormattedTextBox'; -import { ImportElementBox } from './importBox/ImportElementBox'; -import { PresBox } from './trails/PresBox'; -import { PresElementBox } from './trails/PresElementBox'; +import { FieldViewProps } from './FieldView'; type BindingProps = Without<FieldViewProps, 'fieldKey'>; export interface JsxBindings { props: BindingProps; } -class ObserverJsxParser1 extends JsxParser { - constructor(props: any) { - super(props); - observer(this as any); - } -} - -export const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any; - interface HTMLtagProps { Document: Doc; htmltag: string; @@ -116,6 +74,15 @@ export interface DocumentContentsViewProps extends FieldViewProps { } @observer export class DocumentContentsView extends ObservableReactComponent<DocumentContentsViewProps> { + private static DefaultLayoutString: string; + /** + * Set of all available rendering componets for Docs (e.g., ImageBox, CollectionFreeFormView, etc) + */ + private static Components: { [key: string]: any }; + public static Init(defaultLayoutString: string, components:{ [key: string]: any}) { + DocumentContentsView.DefaultLayoutString = defaultLayoutString; + DocumentContentsView.Components = components; + } constructor(props: any) { super(props); makeObservable(this); @@ -124,11 +91,11 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte TraceMobx(); if (this._props.LayoutTemplateString) return this._props.LayoutTemplateString; if (!this.layoutDoc) return '<p>awaiting layout</p>'; - if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, KeyValueBox.LayoutString()); + if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, DocumentContentsView.DefaultLayoutString); const tempLayout = DocCast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')]); const layoutDoc = tempLayout ?? this.layoutDoc; const layout = Cast(layoutDoc[layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(layoutDoc.layout_fieldKey, 'layout')], 'string'); - if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString(); + if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : DocumentContentsView.DefaultLayoutString; if (typeof layout === 'string') return layout; return '<p>Loading layout</p>'; } @@ -223,42 +190,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte key={42} blacklistedAttrs={emptyPath} renderInWrapper={false} - components={{ - FormattedTextBox, - ImageBox, - FontIconBox, - LabelBox, - EquationBox, - FieldView, - CollectionFreeFormView, - CollectionDockingView, - CollectionSchemaView, - CollectionCalendarView, - CollectionView, - WebBox, - KeyValueBox, - PDFBox, - VideoBox, - AudioBox, - RecordingBox, - PresBox, - PresElementBox, - SearchBox, - FunctionPlotBox, - InkingStroke, - LinkBox, - ScriptingBox, - MapBox, - ScreenshotBox, - DataVizBox, - HTMLtag, - ComparisonBox, - LoadingBox, - PhysicsSimulationBox, - SchemaRowBox, - ImportElementBox, - MapPushpinBox, - }} + components={DocumentContentsView.Components} bindings={bindings} jsx={layoutFrame} showWarnings diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index dc597e5ff..8df28a770 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -8,7 +8,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal'; import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simulateMouseClick } from '../../../ClientUtils'; -import { Utils, emptyFunction, emptyPath } from '../../../Utils'; +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 { Id } from '../../../fields/FieldSymbols'; @@ -35,20 +35,21 @@ import { SnappingManager } from '../../util/SnappingManager'; import { UndoManager, undoBatch, undoable } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; -import { DocComponent, ViewBoxInterface } from '../DocComponent'; +import { DocComponent } from '../DocComponent'; import { EditableView } from '../EditableView'; import { FieldsDropdown } from '../FieldsDropdown'; -import { LightboxView } from '../LightboxView'; +import { ObserverJsxParser } from '../ObservableReactComponent'; import { PinProps } from '../PinFuncs'; import { StyleProp } from '../StyleProp'; -import { DocumentContentsView, ObserverJsxParser } from './DocumentContentsView'; +import { ViewBoxInterface } from '../ViewBoxInterface'; +import { DocumentContentsView } from './DocumentContentsView'; import { DocumentLinksButton } from './DocumentLinksButton'; import './DocumentView.scss'; import { FieldViewProps, FieldViewSharedProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; -import { OpenWhere } from './OpenWhere'; +import { OpenWhere, OpenWhereMod } from './OpenWhere'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; -import { PresEffect, PresEffectDirection } from './trails'; +import { PresEffect, PresEffectDirection } from './trails/PresEnums'; export interface DocumentViewProps extends FieldViewSharedProps { hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected @@ -77,7 +78,7 @@ export interface DocumentViewProps extends FieldViewSharedProps { dragStarting?: () => void; dragEnding?: () => void; - parent?: any; + parent?: any; // parent React component view (see CollectionFreeFormDocumentView) } @observer export class DocumentViewInternal extends DocComponent<FieldViewProps & DocumentViewProps>() { @@ -320,7 +321,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document if (this.onDoubleClickHandler?.script) { UndoManager.RunInBatch(() => this.onDoubleClickHandler.script.run(scriptProps, console.log).result?.select && this._props.select(false), 'on double click: ' + this.Document.title); } else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') { - UndoManager.RunInBatch(() => LightboxView.Instance.AddDocTab(this.Document, OpenWhere.lightbox), 'double tap'); + UndoManager.RunInBatch(() => this._props.addDocTab(this.Document, OpenWhere.lightbox), 'double tap'); DocumentView.DeselectAll(); Doc.UnBrushDoc(this.Document); } else { @@ -561,7 +562,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : []; if (this._props.renderDepth === 0) { - appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => LightboxView.Instance.SetLightboxDoc(this.Document), icon: 'external-link-alt' }); + appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' }); } appearanceItems.push({ description: 'Pin', event: () => this._props.pinToPres(this.Document, {}), icon: 'eye' }); !Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template ', event: () => this._props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' }); @@ -980,6 +981,29 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document @observer export class DocumentView extends DocComponent<DocumentViewProps>() { public static ROOT_DIV = 'documentView-effectsWrapper'; + public static addSplit: (Doc: Doc, where: OpenWhereMod) => void; + // Lightbox + public static _lightboxDoc: () => Doc | undefined; + public static _lightboxContains: (view?: DocumentView) => boolean | undefined; + public static _setLightboxDoc: (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => boolean; + /** + * @returns The Doc, if any, being displayed in the lightbox + */ + public static readonly LightboxDoc = () => DocumentView._lightboxDoc?.(); + /** + * @param view + * @returns whether 'view' is anywhere in the rendering hierarchy of the lightbox + */ + public static readonly LightboxContains = (view?: DocumentView) => DocumentView._lightboxContains?.(view); + /** + * Sets the root Doc to render in the lightbox view. + * @param doc + * @param target a Doc within 'doc' to focus on (useful for freeform collections) + * @param future a list of Docs to step through with the arrow buttons of the lightbox + * @param layoutTemplate a template to apply to 'doc' to render it. + * @returns success flag which is currently always true + */ + public static readonly SetLightboxDoc = (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => DocumentView._setLightboxDoc(doc, target, future, layoutTemplate); // Sharing Manager public static ShareOpen: (target?: DocumentView, targetDoc?: Doc) => void; // LinkFollower @@ -998,6 +1022,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { public static addView: (dv: DocumentView) => void | undefined; public static removeView: (dv: DocumentView) => void | undefined; public static addViewRenderedCb: (doc: Opt<Doc>, func: (dv: DocumentView) => any) => boolean; + public static getViews = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []) as DocumentView[]; public static getFirstDocumentView: (toFind: Doc) => DocumentView | undefined; public static getDocumentView: (target: Doc | undefined, preferredCollection?: DocumentView) => Opt<DocumentView>; public static getContextPath: (doc: Opt<Doc>, includeExistingViews?: boolean) => Doc[]; @@ -1032,8 +1057,8 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { public static UniquifyId(inLightbox: boolean | undefined, id: string) { return (inLightbox ? 'lightbox-' : '') + id; } - public ViewGuid = DocumentView.UniquifyId(LightboxView.Contains(this), Utils.GenerateGuid()); // a unique id associated with the main <div>. used by LinkBox's Xanchor to find the arrowhead locations. - public DocUniqueId = DocumentView.UniquifyId(LightboxView.Contains(this), this.Document[Id]); + public ViewGuid = DocumentView.UniquifyId(DocumentView.LightboxContains(this), Utils.GenerateGuid()); // a unique id associated with the main <div>. used by LinkBox's Xanchor to find the arrowhead locations. + public DocUniqueId = DocumentView.UniquifyId(DocumentView.LightboxContains(this), this.Document[Id]); constructor(props: DocumentViewProps) { super(props); @@ -1401,6 +1426,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { }}> <DocumentViewInternal {...this._props} + parent={undefined} fieldKey={this.LayoutFieldKey} DataTransition={this.DataTransition} DocumentView={this.selfView} @@ -1451,58 +1477,52 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { const docId = ClientUtils.CurrentUserEmail() + Doc.GetProto(linkAnchor)[Id] + '-pivotish'; // prettier-ignore DocServer.GetRefField(docId).then(docx => - LightboxView.Instance.SetLightboxDoc( + DocumentView.SetLightboxDoc( (docx as Doc) ?? // reuse existing pivot view of documents, or else create a new collection Docs.Create.StackingDocument([], { title: linkAnchor.title + '-pivot', _width: 500, _height: 500, target: linkAnchor, onViewMounted: ScriptField.MakeScript('updateLinkCollection(this, this.target)') }, docId) ) ); } -} - -export function returnEmptyDocViewList() { - return emptyPath; -} - -// eslint-disable-next-line default-param-last -export function DocFocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) { - let doc = docIn; - const options = optionsIn; - const func = () => { - const cv = DocumentView.getDocumentView(containingDoc); - const dv = DocumentView.getDocumentView(doc, cv); - if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) { - DocumentView.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document)); - } else { - const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc)); - const showDoc = !Doc.IsSystem(container) && !cv ? container : doc; - options.toggleTarget = undefined; - DocumentView.showDocument(showDoc, options, () => DocumentView.showDocument(doc, { ...options, openLocation: undefined })).then(() => { - const cvFound = DocumentView.getDocumentView(containingDoc); - const dvFound = DocumentView.getDocumentView(doc, cvFound); - dvFound && Doc.linkFollowHighlight(dvFound.Document); - }); + // eslint-disable-next-line default-param-last + public static FocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) { + let doc = docIn; + const options = optionsIn; + const func = () => { + const cv = DocumentView.getDocumentView(containingDoc); + const dv = DocumentView.getDocumentView(doc, cv); + if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) { + DocumentView.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document)); + } else { + const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc)); + const showDoc = !Doc.IsSystem(container) && !cv ? container : doc; + options.toggleTarget = undefined; + DocumentView.showDocument(showDoc, options, () => DocumentView.showDocument(doc, { ...options, openLocation: undefined })).then(() => { + const cvFound = DocumentView.getDocumentView(containingDoc); + const dvFound = DocumentView.getDocumentView(doc, cvFound); + dvFound && Doc.linkFollowHighlight(dvFound.Document); + }); + } + }; + if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) { + doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!; } - }; - if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) { - doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!; + if (doc.hidden) { + doc.hidden = false; + options.toggleTarget = false; + setTimeout(func); + } else func(); } - if (doc.hidden) { - doc.hidden = false; - options.toggleTarget = false; - setTimeout(func); - } else func(); } -ScriptingGlobals.add(DocFocusOrOpen); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) { - documentView.iconify(); - documentView.select(false); +ScriptingGlobals.add(function DocFocusOrOpen(docIn: Doc, optionsIn?: FocusViewOptions, containingDoc?: Doc) { + return DocumentView.FocusOrOpen(docIn, optionsIn, containingDoc); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function deiconifyViewToLightbox(documentView: DocumentView) { - LightboxView.Instance.AddDocTab(documentView.Document, OpenWhere.lightbox, 'layout'); // , 0); +ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) { + documentView.iconify(); + documentView.select(false); }); // eslint-disable-next-line prefer-arrow-callback diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index 32d08fbe7..1f5c9b84b 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -11,7 +11,7 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { undoBatch } from '../../util/UndoManager'; import { ViewBoxBaseComponent } from '../DocComponent'; -import { LightboxView } from '../LightboxView'; +import { DocumentView } from './DocumentView'; import './EquationBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import EquationEditor from './formattedText/EquationEditor'; @@ -30,7 +30,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() { componentDidMount() { this._props.setContentViewBox?.(this); - if (Doc.SelectOnLoad === this.Document && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) { + if (Doc.SelectOnLoad === this.Document && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.()))) { this._props.select(false); this._ref.current!.mathField.focus(); diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 66b134889..3f351a072 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -10,8 +10,8 @@ import { ScriptField } from '../../../fields/ScriptField'; import { WebField } from '../../../fields/URLField'; import { dropActionType } from '../../util/DropActionTypes'; import { Transform } from '../../util/Transform'; -import { ViewBoxInterface } from '../DocComponent'; import { PinProps } from '../PinFuncs'; +import { ViewBoxInterface } from '../ViewBoxInterface'; import { DocumentView } from './DocumentView'; import { FocusViewOptions } from './FocusViewOptions'; import { OpenWhere } from './OpenWhere'; diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 397cc15ed..0956be3e9 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -13,8 +13,7 @@ import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { EditableView } from '../EditableView'; import { ObservableReactComponent } from '../ObservableReactComponent'; -import { DefaultStyleProvider } from '../StyleProvider'; -import { returnEmptyDocViewList } from './DocumentView'; +import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider'; import './KeyValueBox.scss'; import './KeyValuePair.scss'; import { OpenWhere } from './OpenWhere'; diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 6caa38a7f..8d6ae9f73 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -16,7 +16,6 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { SnappingManager } from '../../util/SnappingManager'; import { ViewBoxBaseComponent } from '../DocComponent'; import { EditableView } from '../EditableView'; -import { LightboxView } from '../LightboxView'; import { StyleProp } from '../StyleProp'; import { ComparisonBox } from './ComparisonBox'; import { DocumentView } from './DocumentView'; @@ -52,7 +51,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { componentDidMount() { this._props.setContentViewBox?.(this); this._disposers.deleting = reaction( - () => !this.anchor1 && !this.anchor2 && this.DocumentView?.() && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView!())), + () => !this.anchor1 && !this.anchor2 && this.DocumentView?.() && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView!())), empty => { if (empty) { this._hackToSeeIfDeleted = setTimeout(() => { @@ -110,7 +109,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { const getAnchor = (field: FieldResult): Element[] => { const docField = DocCast(field); const doc = docField?.layout_unrendered ? DocCast(docField.annotationOn, docField) : docField; - const ele = document.getElementById(DocumentView.UniquifyId(LightboxView.Contains(this.DocumentView?.()), doc[Id])); + const ele = document.getElementById(DocumentView.UniquifyId(DocumentView.LightboxContains(this.DocumentView?.()), doc[Id])); if (ele?.className === 'linkBox-label') foundParent = true; if (ele?.getBoundingClientRect().width) return [ele]; const eles = Array.from(document.getElementsByClassName(doc[Id])).filter(el => el?.getBoundingClientRect().width); diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index ac8010f11..d7687e03e 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -23,7 +23,7 @@ import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; import { UndoManager, undoable } from '../../../util/UndoManager'; -import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent'; +import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { PinDocView, PinProps } from '../../PinFuncs'; import { SidebarAnnos } from '../../SidebarAnnos'; import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; @@ -63,7 +63,7 @@ type PopupInfo = { }; @observer -export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface { +export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MapBox, fieldKey); } diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index e46e40bfe..07381c7d0 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -50,9 +50,9 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() { this.result = info; this.dataDoc.type = DocumentType.VID; - this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey); + this.dataDoc[this.fieldKey + '_recorded'] = this.dataDoc.layout; // save the recording layout to allow re-recording later + this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey); // then convert the recording box to a video this.dataDoc[this._props.fieldKey] = new VideoField(this.result.accessPaths.client); - this.dataDoc[this.fieldKey + '_recorded'] = true; // stringify the presentation and store it if (presentation?.movements) { const presCopy = { ...presentation }; @@ -143,18 +143,13 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() { public static resumeWorkspaceReplaying(doc: Doc) { const docView = DocumentView.getDocumentView(doc); - if (docView?.ComponentView instanceof VideoBox) { - docView.ComponentView.Play(); - } + docView?.ComponentView?.Play?.(); Doc.UserDoc().workspaceReplayingState = mediaState.Playing; } public static pauseWorkspaceReplaying(doc: Doc) { const docView = DocumentView.getDocumentView(doc); - const videoBox = docView?.ComponentView as VideoBox; - if (videoBox) { - videoBox.Pause(); - } + docView?.ComponentView?.Pause?.(); Doc.UserDoc().workspaceReplayingState = mediaState.Paused; } diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 3b1815f8a..fe7600fa3 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -17,7 +17,6 @@ import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocUtils, FollowLinkScript } from '../../documents/DocUtils'; import { dropActionType } from '../../util/DropActionTypes'; -import { ReplayMovements } from '../../util/ReplayMovements'; import { undoBatch } from '../../util/UndoManager'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { CollectionStackedTimeline, TrimScope } from '../collections/CollectionStackedTimeline'; @@ -32,7 +31,6 @@ import { StyleProp } from '../StyleProp'; import { DocumentView } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; -import { RecordingBox } from './RecordingBox'; import './VideoBox.scss'; /** @@ -101,18 +99,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return field?.url.href ?? vfield?.url.href ?? ''; } - // returns the presentation data if it exists, null otherwise - @computed get presentation() { - const data = this.dataDoc[this.fieldKey + '_presentation']; - return data ? JSON.parse(StrCast(data)) : null; - } - @computed private get timeline() { return this._stackedTimeline; } private get transition() { return this._clicking ? 'left 0.5s, width 0.5s, height 0.5s' : ''; } // css transition for hiding/showing timeline + public get player(): HTMLVideoElement | null { return this._videoRef; } @@ -122,10 +115,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._props.setContentViewBox?.(this); // this tells the DocumentView that this VideoBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the VideoBox when making a link. this.player && this.setPlayheadTime(this.timeline?.clipStart || 0); document.addEventListener('keydown', this.keyEvents, true); - - if (this.presentation) { - ReplayMovements.Instance.setVideoBox(this); - } } componentWillUnmount() { @@ -134,12 +123,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this.Pause(); Object.keys(this._disposers).forEach(d => this._disposers[d]?.()); document.removeEventListener('keydown', this.keyEvents, true); - - if (this.presentation) { - ReplayMovements.Instance.removeVideoBox(); - } } + override PlayerTime = () => this.player?.currentTime; + override Pause = (update: boolean = true) => { + this.pause(update); + !this._keepCurrentlyPlaying && this.removeCurrentlyPlaying(); + }; + // handles key events, when timeline scrubs fade controls @action keyEvents = (e: KeyboardEvent) => { @@ -230,10 +221,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } this._playRegionTimer = undefined; }; - @action Pause = (update: boolean = true) => { - this.pause(update); - !this._keepCurrentlyPlaying && this.removeCurrentlyPlaying(); - }; // toggles video full screen @action public FullScreen = () => { @@ -518,11 +505,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { icon: 'expand-arrows-alt', }); // if the videobox was turned from a recording box - if (this.dataDoc[this.fieldKey + '_recorded'] === true) { + if (this.dataDoc[this.fieldKey + '_recorded']) { subitems.push({ description: 'Recreate recording', event: () => { - this.dataDoc.layout = RecordingBox.LayoutString(this.fieldKey); + this.dataDoc.layout = StrCast(this.dataDoc[this.fieldKey + '_recorded']); // restore the saed recording layout // delete assoicated video data this.dataDoc[this._props.fieldKey] = ''; this.dataDoc[this.fieldKey + '_duration'] = ''; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index b6ef36974..8835ea5e7 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -28,9 +28,8 @@ import { MarqueeOptionsMenu } from '../collections/collectionFreeForm'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; -import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; +import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { Colors } from '../global/globalEnums'; -import { LightboxView } from '../LightboxView'; import { MarqueeAnnotator } from '../MarqueeAnnotator'; import { AnchorMenu } from '../pdf/AnchorMenu'; import { Annotation } from '../pdf/Annotation'; @@ -38,6 +37,7 @@ import { GPTPopup } from '../pdf/GPTPopup/GPTPopup'; import { PinDocView, PinProps } from '../PinFuncs'; import { SidebarAnnos } from '../SidebarAnnos'; import { StyleProp } from '../StyleProp'; +import { ViewBoxInterface } from '../ViewBoxInterface'; import { DocumentView } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; @@ -623,7 +623,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { clearStyleSheetRules(WebBox.webStyleSheet); this._scrollTimer = undefined; const newScrollTop = scrollTop > iframeHeight ? iframeHeight : scrollTop; - if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) { + if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.()))) { this.layoutDoc.thumb = undefined; this.layoutDoc.thumbScrollTop = undefined; this.layoutDoc.thumbNativeWidth = undefined; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 321fdbb91..e354aedb7 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-use-before-define */ /* eslint-disable jsx-a11y/no-static-element-interactions */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -10,7 +11,7 @@ import { inputRules } from 'prosemirror-inputrules'; import { keymap } from 'prosemirror-keymap'; import { Fragment, Mark, Node, Slice } from 'prosemirror-model'; import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transaction } from 'prosemirror-state'; -import { EditorView } from 'prosemirror-view'; +import { EditorView, NodeViewConstructor } from 'prosemirror-view'; import * as React from 'react'; import { BsMarkdownFill } from 'react-icons/bs'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, StopEvent } from '../../../../ClientUtils'; @@ -45,7 +46,6 @@ import { ContextMenu } from '../../ContextMenu'; import { ContextMenuProps } from '../../ContextMenuItem'; import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; -import { LightboxView } from '../../LightboxView'; import { AnchorMenu } from '../../pdf/AnchorMenu'; import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup'; import { PinDocView, PinProps } from '../../PinFuncs'; @@ -58,11 +58,6 @@ import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; import { LinkInfo } from '../LinkDocPreview'; import { OpenWhere } from '../OpenWhere'; -import { DashDocCommentView } from './DashDocCommentView'; -import { DashDocView } from './DashDocView'; -import { DashFieldView } from './DashFieldView'; -import { EquationView } from './EquationView'; -import { FootnoteView } from './FootnoteView'; import './FormattedTextBox.scss'; import { findLinkMark, FormattedTextBoxComment } from './FormattedTextBoxComment'; import { buildKeymap, updateBullets } from './ProsemirrorExampleTransfer'; @@ -70,7 +65,6 @@ import { removeMarkWithAttrs } from './prosemirrorPatches'; import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; -import { SummaryView } from './SummaryView'; // import * as applyDevTools from 'prosemirror-dev-tools'; export interface FormattedTextBoxProps extends FieldViewProps { @@ -82,10 +76,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB public static LayoutString(fieldStr: string) { return FieldView.LayoutString(FormattedTextBox, fieldStr); } - public static blankState = () => EditorState.create(FormattedTextBox.Instance.config); - // eslint-disable-next-line no-use-before-define - public static Instance: FormattedTextBox; - public static LiveTextUndo: UndoManager.Batch | undefined; + private static nodeViews: (self: FormattedTextBox) => { [key: string]: NodeViewConstructor }; + /** + * Initialize the class with all the plugin node view components + * @param nodeViews prosemirror plugins that render a custom UI for specific node types + */ + public static Init(nodeViews: (self: FormattedTextBox) => { [key: string]: NodeViewConstructor }) { + FormattedTextBox.nodeViews = nodeViews; + } + public static LiveTextUndo: UndoManager.Batch | undefined; // undo batch when typing a new text note into a collection static _globalHighlightsCache: string = ''; static _globalHighlights = new ObservableSet<string>(['Audio Tags', 'Text from Others', 'Todo Items', 'Important Items', 'Disagree Items', 'Ignore Items']); static _highlightStyleSheet: any = addStyleSheet(); @@ -189,7 +188,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB constructor(props: FormattedTextBoxProps) { super(props); makeObservable(this); - FormattedTextBox.Instance = this; this._recordingStart = Date.now(); } @@ -1435,14 +1433,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB return true; }, dispatchTransaction: this.dispatchTransaction, - nodeViews: { - dashComment(node: any, view: any, getPos: any) { return new DashDocCommentView(node, view, getPos); }, // prettier-ignore - dashDoc(node: any, view: any, getPos: any) { return new DashDocView(node, view, getPos, self); }, // prettier-ignore - dashField(node: any, view: any, getPos: any) { return new DashFieldView(node, view, getPos, self); }, // prettier-ignore - equation(node: any, view: any, getPos: any) { return new EquationView(node, view, getPos, self); }, // prettier-ignore - summary(node: any, view: any, getPos: any) { return new SummaryView(node, view, getPos); }, // prettier-ignore - footnote(node: any, view: any, getPos: any) { return new FootnoteView(node, view, getPos); }, // prettier-ignore - }, + nodeViews: FormattedTextBox.nodeViews(this), clipboardTextSerializer: this.clipboardTextSerializer, handlePaste: this.handlePaste, }); @@ -1463,7 +1454,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB (this._editorView as any).TextView = this; } - const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, Doc.SelectOnLoad) && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.())); + const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, Doc.SelectOnLoad) && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.())); const selLoadChar = FormattedTextBox.SelectOnLoadChar; if (selectOnLoad) { Doc.SetSelectOnLoad(undefined); diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 6b4f5e073..75492d2f9 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -24,14 +24,12 @@ import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SerializationHelper } from '../../../util/SerializationHelper'; import { SnappingManager } from '../../../util/SnappingManager'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; -import { CollectionDockingView } from '../../collections/CollectionDockingView'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents'; import { CollectionView } from '../../collections/CollectionView'; import { TreeView } from '../../collections/TreeView'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; -import { LightboxView } from '../../LightboxView'; import { pinDataTypes as dataTypes } from '../../PinFuncs'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; @@ -46,6 +44,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); } + private static _getTabDocs: () => Doc[]; + public static Init(tabDocs: () => Doc[]) { + PresBox._getTabDocs = tabDocs; + } static navigateToDocScript: ScriptField; constructor(props: FieldViewProps) { @@ -679,16 +681,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (activeItem.presentation_openInLightbox) { const context = DocCast(targetDoc.annotationOn) ?? targetDoc; if (!DocumentView.getLightboxDocumentView(context)) { - LightboxView.Instance.SetLightboxDoc(context); + DocumentView.SetLightboxDoc(context); } } if (targetDoc) { if (activeItem.presentation_targetDoc instanceof Doc) activeItem.presentation_targetDoc[Animation] = undefined; - DocumentView.addViewRenderedCb(LightboxView.LightboxDoc, () => { + DocumentView.addViewRenderedCb(DocumentView.LightboxDoc(), () => { // if target or the doc it annotates is not in the lightbox, then close the lightbox if (!DocumentView.getLightboxDocumentView(DocCast(targetDoc.annotationOn) ?? targetDoc)) { - LightboxView.Instance.SetLightboxDoc(undefined); + DocumentView.SetLightboxDoc(undefined); } DocumentView.showDocument(targetDoc, options, finished); }); @@ -789,7 +791,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { default: } }); - LightboxView.Instance.SetLightboxDoc(undefined); + DocumentView.SetLightboxDoc(undefined); Doc.RemFromMyOverlay(this.Document); return PresStatus.Edit; }; @@ -892,7 +894,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { exitMinimize = () => { if (Doc.IsInMyOverlay(this.layoutDoc)) { Doc.RemFromMyOverlay(this.Document); - CollectionDockingView.AddSplit(this.Document, OpenWhereMod.right); + DocumentView.addSplit(this.Document, OpenWhereMod.right); } return PresStatus.Edit; }; @@ -2202,9 +2204,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (freeform && layout) doc = this.createTemplate(layout, title); if (!freeform && !layout) doc = Docs.Create.TextDocument('', { _nativeWidth: 400, _width: 225, title: title }); if (doc) { - const tabMap = CollectionDockingView.Instance?.tabMap; - const docTab = tabMap && Array.from(tabMap).find(tab => tab.DashDoc.type === DocumentType.COL)?.DashDoc; - const presCollection = DocumentView.getContextPath(this.activeItem).reverse().lastElement().presentation_targetDoc ?? docTab; + const docTab = PresBox._getTabDocs().find(tdoc => tdoc.type === DocumentType.COL); + const presCollection = DocCast(DocumentView.getContextPath(this.activeItem).reverse().lastElement().presentation_targetDoc, docTab); const data = Cast(presCollection?.data, listSpec(Doc)); const configData = Cast(this.Document.data, listSpec(Doc)); if (data && configData) { |
