diff options
Diffstat (limited to 'src')
49 files changed, 138 insertions, 160 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index bcc016391..2cbc90387 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -259,6 +259,7 @@ export class DocumentOptions { _layout_showCaption?: string; // which field to display in the caption area. leave empty to have no caption _chromeHidden?: BOOLt = new BoolInfo('whether the editing chrome for a document is hidden'); + hideClickBehaviors?: BOOLt = new BoolInfo('whether to hide click behaviors in context menu'); _gridGap?: NUMt = new NumInfo('gap between items in masonry view', false); _xMargin?: NUMt = new NumInfo('gap between left edge of document and start of masonry/stacking layouts', false); _yMargin?: NUMt = new NumInfo('gap between top edge of dcoument and start of masonry/stacking layouts', false); @@ -658,7 +659,7 @@ export namespace Docs { DocumentType.PRES, { layout: { view: PresBox, dataField: defaultDataKey }, - options: { defaultDoubleClick: 'ignore', layout_hideLinkAnchors: true }, + options: { defaultDoubleClick: 'ignore', hideClickBehaviors: true, layout_hideLinkAnchors: true }, }, ], [ diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 70c40c54e..a6ad0f1b3 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -181,7 +181,7 @@ export namespace DragManager { } }; - export function MakeDropTarget(element: HTMLElement, dropFunc: (e: Event, de: DropEvent) => void, doc?: Doc, preDropFunc?: (e: Event, de: DropEvent, targetAction: dropActionType) => void): DragDropDisposer { + export function MakeDropTarget(element: HTMLElement, dropFunc: (e: Event, de: DropEvent) => void, doc: Doc, preDropFunc?: (e: Event, de: DropEvent, targetAction: dropActionType) => void): DragDropDisposer { if ('canDrop' in element.dataset) { throw new Error("Element is already droppable, can't make it droppable again"); } @@ -189,13 +189,13 @@ export namespace DragManager { const handler = (e: Event) => dropFunc(e, (e as CustomEvent<DropEvent>).detail); const preDropHandler = (e: Event) => { const de = (e as CustomEvent<DropEvent>).detail; - (preDropFunc ?? defaultPreDropFunc)(e, de, StrCast(doc?.dropAction) as dropActionType); + (preDropFunc ?? defaultPreDropFunc)(e, de, StrCast(doc.dropAction) as dropActionType); }; element.addEventListener('dashOnDrop', handler); - doc && element.addEventListener('dashPreDrop', preDropHandler); + element.addEventListener('dashPreDrop', preDropHandler); return () => { element.removeEventListener('dashOnDrop', handler); - doc && element.removeEventListener('dashPreDrop', preDropHandler); + element.removeEventListener('dashPreDrop', preDropHandler); delete element.dataset.canDrop; }; } diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 0e5a4f013..e7469a37c 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -172,7 +172,7 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() { } @action.bound - removeDocument(doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean): boolean { + removeDocument(doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean): boolean { const effectiveAcl = GetEffectiveAcl(this.dataDoc); const indocs = doc instanceof Doc ? [doc] : doc; const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin); @@ -189,7 +189,7 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() { Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc); Doc.RemoveDocFromList(doc[DocData], 'proto_embeddings', doc); doc.embedContainer = undefined; - if (recent) { + if (recent && !dontAddToRemoved) { doc.type !== DocumentType.LOADING && Doc.AddDocToList(recent, 'data', doc, undefined, true, true); } }); @@ -214,7 +214,7 @@ export function ViewBoxAnnotatableComponent<P extends FieldViewProps>() { } const first = doc instanceof Doc ? doc : doc[0]; if (!first?._dragOnlyWithinContainer && addDocument !== returnFalse) { - return this.removeDocument(doc, annotationKey, false) && addDocument(doc, annotationKey); + return this.removeDocument(doc, annotationKey, false, true) && addDocument(doc, annotationKey); } return false; }; diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 3c7b5eeca..86b9f5e40 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -479,7 +479,6 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil containerViewPath={returnEmptyDoclist} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFiltersByRanges={returnEmptyFilter} childFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 530fd3121..c7ff7ce47 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -266,7 +266,6 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> { whenChildContentsActiveChanged={emptyFunction} addDocTab={this.AddDocTab} pinToPres={TabDocView.PinDoc} - bringToFront={emptyFunction} onBrowseClickScript={DocumentView.exploreMode} focus={emptyFunction} /> diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 9061e98d4..eca0aca4c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -632,7 +632,6 @@ export class MainView extends ObservableReactComponent<{}> { renderDepth={0} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -661,7 +660,6 @@ export class MainView extends ObservableReactComponent<{}> { PanelHeight={this.mainDocViewHeight} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -756,7 +754,6 @@ export class MainView extends ObservableReactComponent<{}> { isContentActive={returnTrue} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -785,7 +782,6 @@ export class MainView extends ObservableReactComponent<{}> { styleProvider={DefaultStyleProvider} isContentActive={returnTrue} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -913,7 +909,6 @@ export class MainView extends ObservableReactComponent<{}> { fieldKey="data" dropAction="embed" styleProvider={DefaultStyleProvider} - bringToFront={emptyFunction} select={emptyFunction} isAnyChildContentActive={returnFalse} isContentActive={emptyFunction} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 89527c415..20dc6c9fa 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -221,7 +221,6 @@ export class OverlayView extends ObservableReactComponent<{}> { style={{ top: d.type === DocumentType.PRES ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.overlayX}px, ${d.overlayY}px)` }}> <DocumentView Document={d} - bringToFront={emptyFunction} addDocument={undefined} removeDocument={this.removeOverlayDoc} PanelWidth={d[Width]} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 952c8f0b4..208ed56c9 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -319,7 +319,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps whenChildContentsActiveChanged={emptyFunction} addDocTab={returnFalse} pinToPres={emptyFunction} - bringToFront={returnFalse} dontRegisterView={true} /> </div> diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 2aba439c8..58f9784d4 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -259,7 +259,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & if (opacity() === 0) return 'none'; if (props?.isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?. isGroup )? undefined: 'all' - if (props?.isDocumentActive?.() && !props.treeViewDoc) return isInk() ? 'visiblePainted' : 'all'; + if (props?.isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all'; return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active case StyleProp.Decorations: const lock = () => doc?.pointerEvents !== 'none' ? null : ( diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index ba7120b93..5fc33207e 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -123,7 +123,6 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> { onChildClick={this.scriptField} isAnyChildContentActive={returnFalse} isContentActive={returnTrue} - bringToFront={emptyFunction} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} ScreenToLocalTransform={Transform.Identity} diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 2d2cb4860..7e484f3df 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Utils, returnFalse, returnZero } from '../../../Utils'; +import { Utils, emptyFunction, returnFalse, returnZero } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; @@ -81,7 +81,6 @@ export class CollectionCarousel3DView extends CollectionSubView() { isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} PanelWidth={this.panelWidth} PanelHeight={this.panelHeight} - bringToFront={returnFalse} /> ); }; diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 79f5baabe..dbe1536f2 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -78,7 +78,6 @@ export class CollectionCarouselView extends CollectionSubView() { Document={curDoc.layout} TemplateDataDocument={DocCast(curDoc.layout.resolvedDataDoc)} PanelHeight={this.panelHeight} - bringToFront={returnFalse} /> </div> {!carouselShowsCaptions ? null : ( diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 8627ba650..41c5d5b42 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -71,7 +71,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF if (ele) { this._ele = ele; this._props.observeHeight(ele); - this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this)); + this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this), this._props.Document); } }; @action diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 2dad377e0..0f90818ef 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -93,7 +93,6 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { fieldKey="data" dropAction="embed" styleProvider={DefaultStyleProvider} - bringToFront={emptyFunction} select={emptyFunction} isContentActive={returnTrue} isAnyChildContentActive={returnFalse} diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index e6ce5baab..3a9892ed0 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -270,7 +270,6 @@ export class CollectionNoteTakingView extends CollectionSubView() { contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents) as any} whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} addDocTab={this._props.addDocTab} - bringToFront={returnFalse} pinToPres={this._props.pinToPres} /> ); diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index 3f6d3c82e..38846c79d 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -81,7 +81,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV if (ele) { this._ele = ele; this._props.observeHeight(ele); - this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document); } }; @@ -90,11 +90,11 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV } @undoBatch - columnDrop = action((e: Event, de: DragManager.DropEvent) => { + columnDrop = (e: Event, de: DragManager.DropEvent) => { const drop = { docs: de.complete.docDragData?.droppedDocuments, val: this.getValue(this._heading) }; drop.docs?.forEach(d => Doc.SetInPlace(d, this._props.pivotField, drop.val, false)); return true; - }); + }; getValue = (value: string): any => { const parsed = parseInt(value); diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 1394e62ba..5c47d4b9e 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -847,7 +847,6 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch onDoubleClickScript={this._props.layoutDoc.autoPlayAnchors ? undefined : doublescript} ignoreAutoHeight={false} hideResizeHandles={true} - bringToFront={emptyFunction} contextMenuItems={this.contextMenuItems} /> ), diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 0da32a9e0..d436d3c2f 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -358,7 +358,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents) as any} whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} addDocTab={this._props.addDocTab} - bringToFront={returnFalse} pinToPres={this._props.pinToPres} /> ); @@ -682,7 +681,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection styleProvider={this._props.styleProvider} containerViewPath={returnEmptyDoclist} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={this._props.childFilters} childFiltersByRanges={this._props.childFiltersByRanges} searchFilterDocs={this._props.searchFilterDocs} diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 69f1c332d..c455f20d8 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -74,7 +74,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< if (ele) { this._ele = ele; this._props.observeHeight(ele); - this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document); } }; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 0aa74aaba..fdbd1cc90 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -196,10 +196,8 @@ export function CollectionSubView<X>(moreProps?: X) { @undoBatch protected onGesture(e: Event, ge: GestureUtils.GestureEvent) {} - protected onInternalPreDrop(e: Event, de: DragManager.DropEvent) { + protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, dropAction: dropActionType) { if (de.complete.docDragData) { - // override the dropEvent's dropAction - const dropAction = this.layoutDoc.dropAction as dropActionType; // if the dropEvent's dragAction is, say 'embed', but we're just dragging within a collection, we may not actually want to make an embedding. // so we check if our collection has a dropAction set on it and if so, we use that instead. if (dropAction && !de.complete.docDragData.draggedDocuments.some(d => d.embedContainer === this.Document && this.childDocs.includes(d))) { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 4696d7948..cc2cf87aa 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -140,15 +140,11 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree if ((this._mainEle = ele)) this._treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document, this.onInternalPreDrop.bind(this)); }; - protected onInternalPreDrop = (e: Event, de: DragManager.DropEvent) => { - const dropAction = this.layoutDoc.dropAction as dropActionType; + protected onInternalPreDrop = (e: Event, de: DragManager.DropEvent, dropAction: dropActionType) => { const dragData = de.complete.docDragData; if (dragData) { const sameTree = Doc.AreProtosEqual(dragData.treeViewDoc, this.Document) ? true : false; const isAlreadyInTree = () => sameTree || dragData.draggedDocuments.some(d => d.embedContainer === this.Document && this.childDocs.includes(d)); - if (isAlreadyInTree() !== sameTree) { - console.log('WHAAAT'); - } dragData.dropAction = dropAction && !isAlreadyInTree() ? dropAction : sameTree && dragData.dropAction !== 'inSame' ? 'same' : dragData.dropAction; e.stopPropagation(); } @@ -254,7 +250,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree moveDocument={returnFalse} removeDocument={returnFalse} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} - bringToFront={returnFalse} /> ); } @@ -349,7 +344,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree styleProvider={this._props.styleProvider} containerViewPath={returnEmptyDoclist} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={this._props.childFilters} childFiltersByRanges={this._props.childFiltersByRanges} searchFilterDocs={this._props.searchFilterDocs} @@ -453,14 +447,13 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree pointerEvents={this._props.isContentActive() && SnappingManager.IsDragging ? returnAll : returnNone} isAnnotationOverlay={true} isAnnotationOverlayScrollable={true} - childDocumentsActive={this._props.isDocumentActive} + childDocumentsActive={this._props.isContentActive} fieldKey={this._props.fieldKey + '_annotations'} dropAction="move" select={emptyFunction} addDocument={this.addAnnotationDocument} removeDocument={this.remAnnotationDocument} moveDocument={this.moveAnnotationDocument} - bringToFront={emptyFunction} renderDepth={this._props.renderDepth + 1}> {this.content} </CollectionFreeFormView> diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 26ff5cc06..6cef469b6 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -189,7 +189,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'hand-point-right' }); - if (!Doc.noviceMode && !this.Document.annotationOn) { + if (!Doc.noviceMode && !this.Document.annotationOn && !this.Document.hideClickBehaviors) { const existingOnClick = cm.findByDescription('OnClick...'); const onClicks = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : []; const funcs = [ diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index da15f8dc5..9bc3ef822 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -470,7 +470,6 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> { whenChildContentsActiveChanged={this.whenChildContentActiveChanges} focus={this.focusFunc} containerViewPath={returnEmptyDoclist} - bringToFront={emptyFunction} pinToPres={TabDocView.PinDoc} /> {this.disableMinimap() ? null : <TabMinimapView key="minimap" addDocTab={this.addDocTab} PanelHeight={this.PanelHeight} PanelWidth={this.PanelWidth} background={this.miniMapColor} document={this._document} tabView={this.tabView} />} @@ -604,7 +603,6 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps isSelected={returnFalse} dontRegisterView={true} fieldKey={Doc.LayoutFieldKey(this._props.document)} - bringToFront={emptyFunction} addDocument={returnFalse} moveDocument={returnFalse} removeDocument={returnFalse} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 38a2fe978..40933321f 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -4,7 +4,7 @@ import { IconButton, Size } from 'browndash-components'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Utils, emptyFunction, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick } from '../../../Utils'; +import { Utils, emptyFunction, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../Utils'; import { Doc, DocListCast, Field, FieldResult, Opt, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -282,12 +282,13 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { _treeEle: any; protected createTreeDropTarget = (ele: HTMLDivElement) => { this._treedropDisposer?.(); - ele && ((this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this))), this.Document); + ele && ((this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), this.Document, this.preTreeDrop.bind(this))), this.Document); if (this._treeEle) this._props.unobserveHeight(this._treeEle); this._props.observeHeight((this._treeEle = ele)); }; componentWillUnmount() { + this._treedropDisposer?.(); this._renderTimer && clearTimeout(this._renderTimer); Object.values(this._disposers).forEach(disposer => disposer?.()); this._treeEle && this._props.unobserveHeight(this._treeEle); @@ -339,11 +340,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { const before = pt[1] < rect.top + rect.height / 2; const inside = pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length); this._header.current!.className = 'treeView-header'; - if (!this.treeView.outlineMode || DragManager.DocDragData?.treeViewDoc === this.treeView.Document) { - if (inside) this._header.current!.className += ' treeView-header-inside'; - else if (before) this._header.current!.className += ' treeView-header-above'; - else if (!before) this._header.current!.className += ' treeView-header-below'; - } + if (inside) this._header.current!.className += ' treeView-header-inside'; + else if (before) this._header.current!.className += ' treeView-header-above'; + else if (!before) this._header.current!.className += ' treeView-header-below'; e.stopPropagation(); }; @@ -387,9 +386,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { return this._props.addDocument(folder); }; - preTreeDrop = (e: Event, de: DragManager.DropEvent) => { - const dragData = de.complete.docDragData; - dragData && (dragData.dropAction = this.treeView.Document === dragData.treeViewDoc ? 'same' : dragData.dropAction); + preTreeDrop = (e: Event, de: DragManager.DropEvent, docDropAction: dropActionType) => { + // fall through and let the CollectionTreeView handle this since treeView items have no special properties of their own }; @undoBatch @@ -416,7 +414,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { docDragData.dropAction, docDragData.removeDocument, docDragData.moveDocument, - docDragData.treeViewDoc === this.treeView.Document + docDragData.treeViewDoc === this.treeView.Document, + de.embedKey ); e.stopPropagation(); !added && e.preventDefault(); @@ -426,7 +425,16 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { }; dropping: boolean = false; - dropDocuments(droppedDocuments: Doc[], before: boolean, inside: number | boolean, dropAction: dropActionType, removeDocument: DragManager.RemoveFunction | undefined, moveDocument: DragManager.MoveFunction | undefined, forceAdd: boolean) { + dropDocuments( + droppedDocuments: Doc[], + before: boolean, + inside: number | boolean, + dropAction: dropActionType, + removeDocument: DragManager.RemoveFunction | undefined, + moveDocument: DragManager.MoveFunction | undefined, + forceAdd: boolean, + canEmbed?: boolean + ) { const parentAddDoc = (doc: Doc | Doc[]) => this._props.addDocument(doc, undefined, undefined, before); const localAdd = (doc: Doc | Doc[]) => { const innerAdd = (doc: Doc) => { @@ -438,9 +446,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean); }; const addDoc = inside ? localAdd : parentAddDoc; - const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same' || dropAction === 'inSame') && moveDocument; const canAdd = (!this.treeView.outlineMode && !StrCast((inside ? this.Document : this._props.treeViewParent)?.treeView_FreezeChildren).includes('add')) || forceAdd; if (canAdd && (dropAction !== 'inSame' || droppedDocuments.every(d => d.embedContainer === this._props.parentTreeView?.Document))) { + const move = (!dropAction || canEmbed || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same' || dropAction === 'inSame') && moveDocument; this._props.parentTreeView instanceof TreeView && (this._props.parentTreeView.dropping = true); const res = droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false); this._props.parentTreeView instanceof TreeView && (this._props.parentTreeView.dropping = false); @@ -602,7 +610,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { docs.sort((a, b) => (NumCast(a.zIndex) > NumCast(b.zIndex) ? 1 : -1)).forEach((d, i) => (d.zIndex = i)); } const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField; - const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true); + const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false); !dataIsComputed && added && Doc.SetContainer(doc, this.Document); return added; @@ -841,7 +849,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { ? folderOp : Doc.IsSystem(this.Document) ? [] - : this.treeView.fileSysMode && this.Document === Doc.GetProto(this.Document) + : this.treeView.fileSysMode && this.Document === this.Document[DocData] ? [openEmbedding, makeFolder] : this.Document._type_collection === CollectionViewType.Docking ? [] @@ -974,8 +982,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { Document={this.Document} layout_fitWidth={returnTrue} scriptContext={this} - hideDecorationTitle={this.treeView.outlineMode} - hideResizeHandles={this.treeView.outlineMode} + hideDecorations={true} + hideClickBehaviors={true} styleProvider={this.titleStyleProvider} onClickScriptDisable="never" // tree docViews have a script to show fields, etc. containerViewPath={this.treeView.childContainerViewPath} @@ -999,7 +1007,6 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { isDocumentActive={this._props.isContentActive} focus={this.refocus} whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} - bringToFront={emptyFunction} disableBrushing={this.treeView._props.disableBrushing} hideLinkButton={BoolCast(this.treeView.Document.childHideLinkButton)} dontRegisterView={BoolCast(this.treeView.Document.childDontRegisterViews, this._props.dontRegisterView)} @@ -1041,7 +1048,19 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { key="titleheader" ref={this._header} onClick={this.ignoreEvent} - onPointerDown={this.ignoreEvent} + onPointerDown={e => { + this.treeView.isContentActive() && + setupMoveUpEvents( + this, + e, + () => { + this._dref?.startDragging(e.clientX, e.clientY, '' as any); + return true; + }, + returnFalse, + emptyFunction + ); + }} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> <div @@ -1073,22 +1092,22 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { isContentActive={isActive} isDocumentActive={isActive} styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} - hideTitle={asText} fitContentsToBox={returnTrue} - hideDecorationTitle={this.treeView.outlineMode} - hideResizeHandles={this.treeView.outlineMode} - onClickScript={this.onChildClick} - focus={this.refocus} - onKey={this.onKeyDown} + hideTitle={asText} + hideDecorations={true} + hideClickBehaviors={true} hideLinkButton={BoolCast(this.treeView.Document.childHideLinkButton)} dontRegisterView={BoolCast(this.treeView.Document.childDontRegisterViews, this._props.dontRegisterView)} ScreenToLocalTransform={this.docTransform} renderDepth={this._props.renderDepth + 1} + onClickScript={this.onChildClick} + onKey={this.onKeyDown} treeViewDoc={this.treeView?.Document} containerViewPath={this.treeView.childContainerViewPath} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} + focus={this.refocus} addDocument={this._props.addDocument} moveDocument={this.move} removeDocument={this._props.removeDoc} @@ -1098,7 +1117,6 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { addDocTab={this._props.addDocTab} pinToPres={this.treeView._props.pinToPres} disableBrushing={this.treeView._props.disableBrushing} - bringToFront={returnFalse} scriptContext={this} /> </div> @@ -1143,7 +1161,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { const before = pt[1] < rect.top + rect.height / 2; const inside = this.treeView.fileSysMode && !this.Document.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length ? true : false); - const docs = this.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, undefined, false)); + const docs = this.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, undefined, false, false)); }; render() { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7203041e0..53dc389b4 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1243,7 +1243,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection pinToPres={this._props.pinToPres} whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} dragAction={(this.Document.childDragAction ?? this._props.childDragAction) as dropActionType} - bringToFront={this.bringToFront} layout_showTitle={this._props.childlayout_showTitle} dontRegisterView={this._props.dontRegisterView} pointerEvents={this.childPointerEventsFunc} diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 72bdb9b6b..228af78aa 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -79,16 +79,16 @@ export class CollectionLinearView extends CollectionSubView() { @action changeDescriptionSetting = () => { - if (LinkDescriptionPopup.showDescriptions) { - if (LinkDescriptionPopup.showDescriptions === 'ON') { - LinkDescriptionPopup.showDescriptions = 'OFF'; - LinkDescriptionPopup.descriptionPopup = false; + if (LinkDescriptionPopup.Instance.showDescriptions) { + if (LinkDescriptionPopup.Instance.showDescriptions === 'ON') { + LinkDescriptionPopup.Instance.showDescriptions = 'OFF'; + LinkDescriptionPopup.Instance.display = false; } else { - LinkDescriptionPopup.showDescriptions = 'ON'; + LinkDescriptionPopup.Instance.showDescriptions = 'ON'; } } else { - LinkDescriptionPopup.showDescriptions = 'OFF'; - LinkDescriptionPopup.descriptionPopup = false; + LinkDescriptionPopup.Instance.showDescriptions = 'OFF'; + LinkDescriptionPopup.Instance.display = false; } }; @@ -110,7 +110,7 @@ export class CollectionLinearView extends CollectionSubView() { <Tooltip title={<div className="dash-tooltip">{'Toggle description pop-up'} </div>} placement="top"> <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}> - Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : 'ON'} + Labels: {LinkDescriptionPopup.Instance.showDescriptions ? LinkDescriptionPopup.Instance.showDescriptions : 'ON'} </span> </Tooltip> @@ -191,7 +191,6 @@ export class CollectionLinearView extends CollectionSubView() { styleProvider={this._props.styleProvider} containerViewPath={this.childContainerViewPath} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={this._props.childFilters} childFiltersByRanges={this._props.childFiltersByRanges} searchFilterDocs={this._props.searchFilterDocs} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 1fa106b45..b181b59ce 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -4,7 +4,7 @@ import { Button } from 'browndash-components'; import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnFalse } from '../../../../Utils'; +import { emptyFunction, returnFalse } from '../../../../Utils'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { DragManager, dropActionType } from '../../../util/DragManager'; @@ -287,7 +287,6 @@ export class CollectionMulticolumnView extends CollectionSubView() { whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} addDocTab={this._props.addDocTab} pinToPres={this._props.pinToPres} - bringToFront={returnFalse} dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' /> ); diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 97a444b8c..659f7ccdc 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -1,7 +1,7 @@ import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnFalse } from '../../../../Utils'; +import { emptyFunction, returnFalse } from '../../../../Utils'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { DragManager, dropActionType } from '../../../util/DragManager'; @@ -281,7 +281,6 @@ export class CollectionMultirowView extends CollectionSubView() { whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} addDocTab={this._props.addDocTab} pinToPres={this._props.pinToPres} - bringToFront={returnFalse} dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' /> ); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index ec91b25f8..581425d77 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -914,7 +914,6 @@ export class CollectionSchemaView extends CollectionSubView() { whenChildContentsActiveChanged={returnFalse} addDocTab={this._props.addDocTab} pinToPres={this._props.pinToPres} - bringToFront={returnFalse} /> )} </div> @@ -989,7 +988,6 @@ class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaV searchFilterDocs={this._props.schema.searchFilterDocs} rootSelected={this._props.schema.rootSelected} ScreenToLocalTransform={this.screenToLocalXf} - bringToFront={emptyFunction} dragWhenActive={true} isDocumentActive={this._props.schema._props.childDocumentsActive?.() ? this._props.schema._props.isDocumentActive : this._props.schema.isContentActive} isContentActive={emptyFunction} diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index fda5764dd..dbaa6e110 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -82,7 +82,6 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro setHeight: returnFalse, select: emptyFunction, dragAction: 'move', - bringToFront: emptyFunction, renderDepth: 1, isContentActive: returnFalse, whenChildContentsActiveChanged: emptyFunction, diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx index 31841c596..c9e3c203d 100644 --- a/src/client/views/linking/LinkPopup.tsx +++ b/src/client/views/linking/LinkPopup.tsx @@ -7,7 +7,7 @@ import { Doc } from '../../../fields/Doc'; import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; import { DefaultStyleProvider } from '../StyleProvider'; -import { OpenWhere } from '../nodes/DocumentView'; +import { OpenWhere, returnEmptyDocViewList } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { SearchBox } from '../search/SearchBox'; import './LinkPopup.scss'; @@ -61,6 +61,7 @@ export class LinkPopup extends React.Component<LinkPopupProps> { <SearchBox Document={Doc.MySearcher} + docViewPath={returnEmptyDocViewList} linkFrom={linkDoc} linkCreateAnchor={this.props.linkCreateAnchor} linkSearch={true} @@ -81,7 +82,6 @@ export class LinkPopup extends React.Component<LinkPopupProps> { renderDepth={0} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx index ed575c329..12b9870ca 100644 --- a/src/client/views/newlightbox/NewLightboxView.tsx +++ b/src/client/views/newlightbox/NewLightboxView.tsx @@ -311,7 +311,6 @@ export class NewLightboxView extends React.Component<LightboxViewProps> { whenChildContentsActiveChanged={emptyFunction} addDocTab={this.addDocTab} pinToPres={TabDocView.PinDoc} - bringToFront={emptyFunction} onBrowseClickScript={DocumentView.exploreMode} focus={emptyFunction} /> diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 2b71fd156..8a38ef663 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -568,8 +568,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const [xp, yp] = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y); de.complete.docDragData && this.timeline?.internalDocDrop(e, de, de.complete.docDragData, xp); }, - this.layoutDoc, - undefined + this.layoutDoc ); } }; @@ -718,7 +717,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { renderDepth={this._props.renderDepth + 1} startTag={'_timecodeToShow' /* audioStart */} endTag={'_timecodeToHide' /* audioEnd */} - bringToFront={emptyFunction} playFrom={this.playFrom} setTime={this.setPlayheadTime} playing={this.playing} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 9538cebb2..d1e141061 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -150,6 +150,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte // these are the properties in DocumentViewProps that need to be removed to pass on only DocumentSharedViewProps to the FieldViews 'hideResizeHandles', 'hideTitle', + 'bringToFront', 'contentPointerEvents', 'LayoutTemplateString', 'LayoutTemplate', diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3e5e43b47..76ad29f60 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -255,17 +255,17 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document { fireImmediately: true } ); } - preDropFunc = (e: Event, de: DragManager.DropEvent) => { - const dropAction = this.layoutDoc.dropAction as dropActionType; - if (de.complete.docDragData && this.isContentActive() && !this._props.treeViewDoc) { - dropAction && (de.complete.docDragData.dropAction = dropAction); + preDrop = (e: Event, de: DragManager.DropEvent, dropAction: dropActionType) => { + const dragData = de.complete.docDragData; + if (dragData && this.isContentActive() && !this.props.dontRegisterView) { + dragData.dropAction = dropAction ? dropAction : dragData.dropAction; e.stopPropagation(); } }; setupHandlers() { this.cleanupHandlers(false); if (this._mainCont.current) { - this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this.Document, this.preDropFunc); + this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this.Document, this.preDrop); } } @@ -311,7 +311,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document if (documentView && !this.Document.ignoreClick && this._props.renderDepth >= 0 && Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) { let stopPropagate = true; let preventDefault = true; - !this.layoutDoc._keepZWhenDragged && this._props.bringToFront(this.Document); + !this.layoutDoc._keepZWhenDragged && this._props.bringToFront?.(this.Document); if (this._doubleTap) { const defaultDblclick = this._props.defaultDoubleClick?.() || this.Document.defaultDoubleClick; if (this.onDoubleClickHandler?.script) { @@ -375,7 +375,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document const sendToBack = e.altKey; this._singleClickFunc = // prettier-ignore - clickFunc ?? (() => (sendToBack ? documentView._props.bringToFront(this.Document, true) : + clickFunc ?? (() => (sendToBack ? documentView._props.bringToFront?.(this.Document, true) : this._componentView?.select?.(e.ctrlKey || e.metaKey, e.shiftKey) ?? this._props.select(e.ctrlKey||e.shiftKey, e.metaKey))); const waitFordblclick = this._props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick; @@ -610,40 +610,38 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document !Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template ', event: () => this._props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' }); !appearance && appearanceItems.length && cm.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'compass' }); - if (!Doc.IsSystem(this.Document) && this.Document.type !== DocumentType.PRES && ![CollectionViewType.Docking, CollectionViewType.Tree].includes(this.Document._type_collection as any)) { + if (this._props.bringToFront) { + const zorders = cm.findByDescription('ZOrder...'); + const zorderItems: ContextMenuProps[] = zorders && 'subitems' in zorders ? zorders.subitems : []; + zorderItems.push({ description: 'Bring to Front', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront?.(dv.Document, false)), icon: 'arrow-up' }); + zorderItems.push({ description: 'Send to Back', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront?.(dv.Document, true)), icon: 'arrow-down' }); + zorderItems.push({ + description: !this.layoutDoc._keepZDragged ? 'Keep ZIndex when dragged' : 'Allow ZIndex to change when dragged', + event: undoBatch(action(() => (this.layoutDoc._keepZWhenDragged = !this.layoutDoc._keepZWhenDragged))), + icon: 'hand-point-up', + }); + !zorders && cm.addItem({ description: 'Z Order...', addDivider: true, noexpand: true, subitems: zorderItems, icon: 'layer-group' }); + } + + if (!Doc.IsSystem(this.Document) && !this.Document.hideClickBehaviors && !this._props.hideClickBehaviors) { const existingOnClick = cm.findByDescription('OnClick...'); const onClicks: ContextMenuProps[] = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : []; - if (this._props.bringToFront !== emptyFunction) { - const zorders = cm.findByDescription('ZOrder...'); - const zorderItems: ContextMenuProps[] = zorders && 'subitems' in zorders ? zorders.subitems : []; - zorderItems.push({ description: 'Bring to Front', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront(dv.Document, false)), icon: 'arrow-up' }); - zorderItems.push({ description: 'Send to Back', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront(dv.Document, true)), icon: 'arrow-down' }); - zorderItems.push({ - description: !this.layoutDoc._keepZDragged ? 'Keep ZIndex when dragged' : 'Allow ZIndex to change when dragged', - event: undoBatch(action(() => (this.layoutDoc._keepZWhenDragged = !this.layoutDoc._keepZWhenDragged))), - icon: 'hand-point-up', - }); - !zorders && cm.addItem({ description: 'Z Order...', addDivider: true, noexpand: true, subitems: zorderItems, icon: 'layer-group' }); - } - onClicks.push({ description: 'Enter Portal', event: this.makeIntoPortal, icon: 'window-restore' }); !Doc.noviceMode && onClicks.push({ description: 'Toggle Detail', event: this.setToggleDetail, icon: 'concierge-bell' }); - if (!this._props.treeViewDoc) { - if (!this.Document.annotationOn) { - const options = cm.findByDescription('Options...'); - const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : []; - !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'compass' }); - - onClicks.push({ description: this.onClickHandler ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(false, false), icon: 'link' }); - !Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' }); - !existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' }); - } else if (LinkManager.Links(this.Document).length) { - onClicks.push({ description: 'Restore On Click default', event: () => this.noOnClick(), icon: 'link' }); - onClicks.push({ description: 'Follow Link on Click', event: () => this.followLinkOnClick(), icon: 'link' }); - !existingOnClick && cm.addItem({ description: 'OnClick...', subitems: onClicks, icon: 'mouse-pointer' }); - } + if (!this.Document.annotationOn) { + const options = cm.findByDescription('Options...'); + const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : []; + !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'compass' }); + + onClicks.push({ description: this.onClickHandler ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(false, false), icon: 'link' }); + !Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' }); + !existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' }); + } else if (LinkManager.Links(this.Document).length) { + onClicks.push({ description: 'Restore On Click default', event: () => this.noOnClick(), icon: 'link' }); + onClicks.push({ description: 'Follow Link on Click', event: () => this.followLinkOnClick(), icon: 'link' }); + !existingOnClick && cm.addItem({ description: 'OnClick...', subitems: onClicks, icon: 'mouse-pointer' }); } } @@ -727,8 +725,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document documentationLink = 'https://brown-dash.github.io/Dash-Documentation/documents/dataViz/'; break; } - // Add link to help documentation - if (!this._props.treeViewDoc && documentationDescription && documentationLink) { + // Add link to help documentation (unless the doc contents have been overriden in which case the documentation isn't relevant) + if (!this.docContents && documentationDescription && documentationLink) { helpItems.push({ description: documentationDescription, event: () => window.open(documentationLink, '_blank'), @@ -996,12 +994,11 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document TraceMobx(); const highlighting = this.highlighting; const borderPath = this.borderPath; - const boxShadow = - this._props.treeViewDoc || !highlighting - ? this.boxShadow - : highlighting && this.borderRounding && highlighting.highlightStyle !== 'dashed' - ? `0 0 0 ${highlighting.highlightIndex}px ${highlighting.highlightColor}` - : this.boxShadow || (this.Document.isTemplateForField ? 'black 0.2vw 0.2vw 0.8vw' : undefined); + const boxShadow = !highlighting + ? this.boxShadow + : highlighting && this.borderRounding && highlighting.highlightStyle !== 'dashed' + ? `0 0 0 ${highlighting.highlightIndex}px ${highlighting.highlightColor}` + : this.boxShadow || (this.Document.isTemplateForField ? 'black 0.2vw 0.2vw 0.8vw' : undefined); const renderDoc = this.renderDoc({ borderRadius: this.borderRounding, outline: highlighting && !this.borderRounding && !highlighting.highlightStroke ? `${highlighting.highlightColor} ${highlighting.highlightStyle} ${highlighting.highlightIndex}px` : 'solid 0px', @@ -1219,7 +1216,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { } @computed get getBounds() { - if (!this._docViewInternal?._contentDiv || this._props.treeViewDoc || Doc.AreProtosEqual(this.Document, Doc.UserDoc())) { + if (!this._docViewInternal?._contentDiv || Doc.AreProtosEqual(this.Document, Doc.UserDoc())) { return undefined; } if (this._docViewInternal._componentView?.screenBounds?.()) { @@ -1282,7 +1279,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { const deiconifyLayout = Cast(this.Document.deiconifyLayout, 'string', null); this.switchViews(deiconifyLayout ? true : false, deiconifyLayout, finalFinished); this.Document.deiconifyLayout = undefined; - this._props.bringToFront(this.Document); + this._props.bringToFront?.(this.Document); } } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 5bb295565..3cf0fabc2 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -54,6 +54,7 @@ export interface FieldViewSharedProps { forceAutoHeight?: boolean; ignoreAutoHeight?: boolean; disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over. + hideClickBehaviors?: boolean; // whether to suppress menu item options for changing click behaviors CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; containerViewPath?: () => DocumentView[]; fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document @@ -86,7 +87,7 @@ export interface FieldViewSharedProps { moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => boolean; pinToPres: (document: Doc, pinProps: PinProps) => void; ScreenToLocalTransform: () => Transform; - bringToFront: (doc: Doc, sendToBack?: boolean) => void; + bringToFront?: (doc: Doc, sendToBack?: boolean) => void; waitForDoubleClickToClick?: () => 'never' | 'always' | undefined; defaultDoubleClick?: () => 'default' | 'ignore' | undefined; pointerEvents?: () => Opt<string>; @@ -108,7 +109,6 @@ export interface FieldViewProps extends FieldViewSharedProps { // See currentUserUtils headerTemplate for examples of creating text boxes from html which set some of these fields // Also, see InkingStroke for examples of creating text boxes from render() methods which set some of these fields backgroundColor?: string; - treeViewDoc?: Doc; color?: string; height?: number; width?: number; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 2a10bd766..923aead64 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -227,7 +227,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl this._props.addDocTab(cropping, OpenWhere.inParent); } DocumentManager.Instance.AddViewRenderedCb(cropping, dv => setTimeout(() => (dv.ComponentView as ImageBox).setNativeSize(), 200)); - this._props.bringToFront(cropping); + this._props.bringToFront?.(cropping); return cropping; }; diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 7c532f33f..f9e8ce4f3 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -114,7 +114,6 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> { isSelected: returnFalse, setHeight: returnFalse, select: emptyFunction, - bringToFront: emptyFunction, renderDepth: 1, isContentActive: returnFalse, whenChildContentsActiveChanged: emptyFunction, diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 2d54da0ed..4b242649a 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -293,7 +293,6 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps focus={emptyFunction} whenChildContentsActiveChanged={returnFalse} ignoreAutoHeight={true} // need to ignore layout_autoHeight otherwise layout_autoHeight text boxes will expand beyond the preview panel size. - bringToFront={returnFalse} NativeWidth={Doc.NativeWidth(this._targetDoc) ? () => Doc.NativeWidth(this._targetDoc) : undefined} NativeHeight={Doc.NativeHeight(this._targetDoc) ? () => Doc.NativeHeight(this._targetDoc) : undefined} /> diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 0eb3ffc3d..1274220b6 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -134,7 +134,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); } - this._props.bringToFront(cropping); + this._props.bringToFront?.(cropping); CreateImage( '', diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index a6c524881..40647feff 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -855,7 +855,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl renderDepth={this._props.renderDepth + 1} startTag={'_timecodeToShow' /* videoStart */} endTag={'_timecodeToHide' /* videoEnd */} - bringToFront={emptyFunction} playFrom={this.playFrom} setTime={this.setPlayheadTime} playing={this.playing} @@ -928,7 +927,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); } - this._props.bringToFront(cropping); + this._props.bringToFront?.(cropping); return cropping; }; savedAnnotations = () => this._savedAnnotations; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 5776cf6a6..5a07540da 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -983,7 +983,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem childFilters={childFilters} select={emptyFunction} isAnyChildContentActive={returnFalse} - bringToFront={emptyFunction} styleProvider={this.childStyleProvider} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} removeDocument={this.removeDocument} diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index bc49ed23d..7335c9286 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -217,7 +217,6 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn PanelHeight={this._dashDoc[Height]} focus={this.outerFocus} whenChildContentsActiveChanged={this._props.tbox.whenChildContentsActiveChanged} - bringToFront={emptyFunction} dontRegisterView={false} childFilters={this._props.tbox?._props.childFilters} childFiltersByRanges={this._props.tbox?._props.childFiltersByRanges} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 38400d2e7..731ab1d53 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -89,6 +89,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps private _scrollRef: React.RefObject<HTMLDivElement> = React.createRef(); private _editorView: Opt<EditorView>; public _applyingChange: string = ''; + private _inDrop = false; private _finishingLink = false; private _searchIndex = 0; private _lastTimedMark: Mark | undefined = undefined; @@ -355,7 +356,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps textChange && (dataDoc[this.fieldKey + '_modificationDate'] = new DateField(new Date(Date.now()))); if ((!prevData && !protoData) || newText || (!newText && !templateData)) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) - if ((this._finishingLink || this._props.isContentActive()) && removeSelection(newJson) !== removeSelection(prevData?.Data)) { + if ((this._finishingLink || this._props.isContentActive() || this._inDrop) && removeSelection(newJson) !== removeSelection(prevData?.Data)) { const numstring = NumCast(dataDoc[this.fieldKey], null); dataDoc[this.fieldKey] = numstring !== undefined ? Number(newText) : new RichTextField(newJson, newText); dataDoc[this.fieldKey + '_noTemplate'] = true; // mark the data field as being split from the template if it has been edited @@ -571,8 +572,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (dragData) { const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc.proto), this.fieldKey) ? DocCast(this.layoutDoc.proto) : this.dataDoc; const effectiveAcl = GetEffectiveAcl(dataDoc); - const draggedDoc = dragData.draggedDocuments.lastElement(); + const draggedDoc = dragData.droppedDocuments.lastElement(); let added: Opt<boolean>; + const dropAction = dragData.dropAction || dragData.userDropAction; if ([AclEdit, AclAdmin, AclSelfEdit].includes(effectiveAcl)) { // replace text contents when dragging with Alt if (de.altKey) { @@ -582,7 +584,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } // embed document when drag marked as embed - } else if (de.embedKey) { + } else if (de.embedKey || dropAction) { const node = schema.nodes.dashDoc.create({ width: NumCast(draggedDoc._width), height: NumCast(draggedDoc._height), @@ -590,20 +592,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps docId: draggedDoc[Id], float: 'unset', }); - if (!['embed', 'copy'].includes((dragData.dropAction ?? '') as any)) { + if (!['embed', 'copy'].includes((dropAction ?? '') as any)) { added = dragData.removeDocument?.(draggedDoc) ? true : false; + } else { + added = true; } if (added) { draggedDoc._freeform_fitContentsToBox = true; Doc.SetContainer(draggedDoc, this.Document); const view = this._editorView!; try { + this._inDrop = true; const pos = view.posAtCoords({ left: de.x, top: de.y })?.pos; pos && view.dispatch(view.state.tr.insert(pos, node)); added = pos ? true : false; // pos will be null if you don't drop onto an actual text location } catch (e) { console.log('Drop failed', e); added = false; + } finally { + this._inDrop = false; } } } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 9e5ea9524..667bc2f5c 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -2607,6 +2607,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { ignoreUnrendered={true} childDragAction="move" setContentViewBox={emptyFunction} + hideClickBehaviors={true} //childLayoutFitWidth={returnTrue} childOpacity={returnOne} childClickScript={PresBox.navigateToDocScript} diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 7e68711fa..5b2aa1cde 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -128,7 +128,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() { whenChildContentsActiveChanged={returnFalse} addDocTab={returnFalse} pinToPres={returnFalse} - bringToFront={returnFalse} /> </div> ); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index ba7286111..0d4cfda88 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -535,7 +535,6 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { isAnnotationOverlayScrollable={true} childFilters={childFilters} select={emptyFunction} - bringToFront={emptyFunction} styleProvider={this.childStyleProvider} /> </div> diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index 5828313c8..4155800b8 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -104,7 +104,6 @@ export class TopBar extends React.Component { fieldKey="data" dropAction="embed" styleProvider={DefaultStyleProvider} - bringToFront={emptyFunction} select={emptyFunction} isContentActive={returnTrue} isAnyChildContentActive={returnFalse} diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 9d68ea731..c31e73b42 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -398,7 +398,6 @@ export class MobileInterface extends React.Component { styleProvider={this.whitebackground} containerViewPath={returnEmptyDoclist} whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} |