From bc19fd4221c1bd06135c894e5ed2edcfdb61b0be Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 27 Jul 2023 15:09:35 -0400
Subject: fixed FontIconBox scripts to set 'this' to fix tool bars buttons not
 working. enabled access to contextMenu in treeView and topBar even when
 hideContextMenu is set

---
 src/client/views/collections/TreeView.tsx | 63 +++++++++++++------------------
 1 file changed, 27 insertions(+), 36 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index d904749b1..51c70633c 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -222,10 +222,8 @@ export class TreeView extends React.Component<TreeViewProps> {
             this.treeViewOpen = !this.treeViewOpen;
         } else {
             // choose an appropriate embedding or make one. --- choose the first embedding that (1) user owns,  (2) has no context field ... otherwise make a new embedding
-            const bestEmbedding =  docView.rootDoc.author === Doc.CurrentUserEmail && !Doc.IsDataProto(docView.props.Document)
-                    ? docView.rootDoc
-                    : Doc.BestEmbedding(docView.rootDoc);
-              this.props.addDocTab(bestEmbedding, OpenWhere.lightbox);
+            const bestEmbedding = docView.rootDoc.author === Doc.CurrentUserEmail && !Doc.IsDataProto(docView.props.Document) ? docView.rootDoc : Doc.BestEmbedding(docView.rootDoc);
+            this.props.addDocTab(bestEmbedding, OpenWhere.lightbox);
         }
     };
 
@@ -540,8 +538,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         TraceMobx();
         const expandKey = this.treeViewExpandedView;
         const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string; icon: JSX.Element | string } }) ?? {};
-        const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color)
-        console.log("tree view", color, this.doc.title, Doc.IsSystem(this.doc))
+        const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color);
+        console.log('tree view', color, this.doc.title, Doc.IsSystem(this.doc));
         if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) {
             const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
             const sortKeys = Object.keys(sortings);
@@ -581,9 +579,10 @@ export class TreeView extends React.Component<TreeViewProps> {
                 );
             }
             return (
-                <div style={{ 
-                    color: color
-                 }}>
+                <div
+                    style={{
+                        color: color,
+                    }}>
                     {!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : (
                         <div className={'treeView-sorting'}>
                             <IconButton
@@ -725,26 +724,19 @@ export class TreeView extends React.Component<TreeViewProps> {
                 }>
                 {this.props.treeView.outlineMode ? (
                     !(this.doc.text as RichTextField)?.Text ? null : (
-                        <IconButton
-                            color={color} 
-                            icon={<FontAwesomeIcon 
-                            icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />}
-                            size={Size.XSMALL}
-                        />
+                        <IconButton color={color} icon={<FontAwesomeIcon icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />} size={Size.XSMALL} />
                     )
                 ) : (
                     <div className="treeView-bulletIcons" style={{ color: Doc.IsSystem(DocCast(this.doc.proto)) ? 'red' : undefined }}>
-                        {this.onCheckedClick ? <IconButton
-                            color={color} 
-                            icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />}
-                            size={Size.XSMALL}
-                        /> : 
+                        {this.onCheckedClick ? (
                             <IconButton
-                                color={color} 
-                                icon={<FontAwesomeIcon icon={iconType as IconProp} />}
+                                color={color}
+                                icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />}
                                 size={Size.XSMALL}
                             />
-                        }
+                        ) : (
+                            <IconButton color={color} icon={<FontAwesomeIcon icon={iconType as IconProp} />} size={Size.XSMALL} />
+                        )}
                     </div>
                 )}
             </div>
@@ -776,17 +768,15 @@ export class TreeView extends React.Component<TreeViewProps> {
         return this.props.treeViewHideHeaderFields() || this.doc.treeViewHideHeaderFields ? null : (
             <>
                 {customHeaderButtons} {/* e.g.,. hide button is set by dashboardStyleProvider */}
-                {this.doc._layout_hideContextMenu ? null : (
-                    <IconButton
-                        color={color} 
-                        icon={<FontAwesomeIcon icon="bars" />}
-                        size={Size.XSMALL}
-                        onClick={e => {
-                            this.showContextMenu(e);
-                            e.stopPropagation();
-                        }}
-                    />
-                )}
+                <IconButton
+                    color={color}
+                    icon={<FontAwesomeIcon icon="bars" />}
+                    size={Size.XSMALL}
+                    onClick={e => {
+                        this.showContextMenu(e);
+                        e.stopPropagation();
+                    }}
+                />
                 {Doc.noviceMode ? null : this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? null : (
                     <span className="collectionTreeView-keyHeader" title="type of expanded data" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
                         {this.treeViewExpandedView}
@@ -1015,9 +1005,10 @@ export class TreeView extends React.Component<TreeViewProps> {
                     onPointerEnter={this.onPointerEnter}
                     onPointerLeave={this.onPointerLeave}>
                     {contents}
-                    <div className={`treeView-background`}
+                    <div
+                        className={`treeView-background`}
                         style={{
-                            background: StrCast(Doc.UserDoc().userColor)
+                            background: StrCast(Doc.UserDoc().userColor),
                         }}
                     />
                 </div>
-- 
cgit v1.2.3-70-g09d2


From 5fd41117708e496113589f6a00cd5ef7f1bb9a53 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 27 Jul 2023 15:36:52 -0400
Subject: removed delete from treeview context menu. fixed close in treeView to
 not readd when closing from recently Closed.

---
 src/client/views/DocComponent.tsx         | 2 +-
 src/client/views/collections/TreeView.tsx | 4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index a41fc8ded..8fe5c2e01 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -145,7 +145,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
             const toRemove = value.filter(v => docs.includes(v));
 
             if (toRemove.length !== 0) {
-                const recent = Doc.MyRecentlyClosed;
+                const recent = this.rootDoc !== Doc.MyRecentlyClosed ? Doc.MyRecentlyClosed : undefined;
                 toRemove.forEach(doc => {
                     leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey);
                     Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 51c70633c..a04f640df 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -342,7 +342,6 @@ export class TreeView extends React.Component<TreeViewProps> {
         TreeView._editTitleOnLoad = { id: folder[Id], parent: this.props.parentTreeView };
         return this.props.addDocument(folder);
     };
-    deleteItem = () => this.props.removeDoc?.(this.doc);
 
     preTreeDrop = (e: Event, de: DragManager.DropEvent) => {
         const dragData = de.complete.docDragData;
@@ -793,7 +792,6 @@ export class TreeView extends React.Component<TreeViewProps> {
     };
     contextMenuItems = () => {
         const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: 'any' })!, icon: 'folder-plus', label: 'New Folder' };
-        const deleteItem = { script: ScriptField.MakeFunction(`scriptContext.deleteItem()`, { scriptContext: 'any' })!, icon: 'folder-plus', label: 'Delete' };
         const folderOp = this.childDocs?.length ? [makeFolder] : [];
         const openEmbedding = { script: ScriptField.MakeFunction(`openDoc(getEmbedding(self), "${OpenWhere.addRight}")`)!, icon: 'copy', label: 'Open New Embedding' };
         const focusDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, icon: 'eye', label: 'Focus or Open' };
@@ -807,7 +805,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 ? [openEmbedding, makeFolder]
                 : this.doc._type_collection === CollectionViewType.Docking
                 ? []
-                : [deleteItem, openEmbedding, focusDoc]),
+                : [openEmbedding, focusDoc]),
         ];
     };
     childContextMenuItems = () => {
-- 
cgit v1.2.3-70-g09d2


From 9c18c60760098e0df4fddb6dccf391c235e6e0e4 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 27 Jul 2023 22:37:42 -0400
Subject: fixed importElementBox and made importBox be a masonry view.  fixed
 clicking background of importBox to deselect everything. fixed masonry view
 documennt screentolocal and fixed  column handle placement.  fixed 'never'
 disable click script flag.  fixed color of documentdeocrations title.

---
 src/Utils.ts                                       |  2 +-
 src/client/documents/Documents.ts                  | 21 +++++-
 src/client/util/CurrentUserUtils.ts                | 16 ++--
 src/client/util/SelectionManager.ts                |  3 +
 src/client/views/DocumentDecorations.tsx           |  8 +-
 .../collections/CollectionMasonryViewFieldRow.tsx  | 40 ++++++----
 .../views/collections/CollectionStackingView.scss  |  1 +
 .../views/collections/CollectionStackingView.tsx   | 25 +++---
 src/client/views/collections/TreeView.tsx          |  7 +-
 src/client/views/nodes/DocumentContentsView.tsx    |  4 +-
 src/client/views/nodes/DocumentView.tsx            | 13 +---
 .../views/nodes/importBox/ImportElementBox.tsx     | 88 +++++++---------------
 12 files changed, 116 insertions(+), 112 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 599c6456a..8b9fe2aab 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -80,7 +80,7 @@ export namespace Utils {
         }
     }
 
-    export function GetScreenTransform(ele?: HTMLElement): { scale: number; translateX: number; translateY: number } {
+    export function GetScreenTransform(ele?: HTMLElement | null): { scale: number; translateX: number; translateY: number } {
         if (!ele) {
             return { scale: 1, translateX: 1, translateY: 1 };
         }
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 5ef033e35..ff427b96c 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -58,6 +58,7 @@ import { SliderBox } from '../views/nodes/SliderBox';
 import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
 import { PresBox } from '../views/nodes/trails/PresBox';
 import { PresElementBox } from '../views/nodes/trails/PresElementBox';
+import { ImportElementBox } from '../views/nodes/importBox/ImportElementBox';
 import { VideoBox } from '../views/nodes/VideoBox';
 import { WebBox } from '../views/nodes/WebBox';
 import { SearchBox } from '../views/search/SearchBox';
@@ -354,6 +355,7 @@ export class DocumentOptions {
     onDoubleClick?: ScriptField;
     onChildClick?: ScriptField; // script given to children of a collection to execute when they are clicked
     onChildDoubleClick?: ScriptField; // script given to children of a collection to execute when they are double clicked
+    onClickScriptDisable?: STRt = new StrInfo('"always" disable click script, "never" disable click script, or default');
     defaultDoubleClick?: 'ignore' | 'default'; // ignore double clicks, or deafult (undefined) means open document full screen
     waitForDoubleClickToClick?: 'always' | 'never' | 'default'; // whether a click function wait for double click to expire.  'default' undefined = wait only if there's a click handler, "never" = never wait, "always" = alway wait
     onPointerDown?: ScriptField;
@@ -620,7 +622,7 @@ export namespace Docs {
                 DocumentType.WEBCAM,
                 {
                     layout: { view: RecordingBox, dataField: defaultDataKey },
-                    options: { systemIcon: 'BsFillCameraVideoFill'  },
+                    options: { systemIcon: 'BsFillCameraVideoFill' },
                 },
             ],
             [
@@ -693,7 +695,22 @@ export namespace Docs {
                 {
                     data: '',
                     layout: { view: PhysicsSimulationBox, dataField: defaultDataKey, _width: 1000, _height: 800 },
-                    options: { _height: 100, layout_forceReflow: true, nativeHeightUnfrozen: true, mass1: '', mass2: '', nativeDimModifiable: true, position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: '', systemIcon: 'BsShareFill' },
+                    options: {
+                        _height: 100,
+                        layout_forceReflow: true,
+                        nativeHeightUnfrozen: true,
+                        mass1: '',
+                        mass2: '',
+                        nativeDimModifiable: true,
+                        position: '',
+                        acceleration: '',
+                        pendulum: '',
+                        spring: '',
+                        wedge: '',
+                        simulation: '',
+                        review: '',
+                        systemIcon: 'BsShareFill',
+                    },
                 },
             ],
         ]);
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 2e4fb0f1c..a86011042 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -344,13 +344,13 @@ export class CurrentUserUtils {
       const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails";
         return [
             { title: "Dashboards",      toolTip: "Dashboards",      target: this.setupDashboards(doc, "myDashboards"),         ignoreClick: true, icon: "desktop",     funcs: {hidden: "IsNoviceMode()"} },
-            { title: "Search",          toolTip: "Search ⌘F",      target: this.setupSearcher(doc, "mySearcher"),             ignoreClick: true, icon: "search",      },
+            { title: "Search",          toolTip: "Search ⌘F",       target: this.setupSearcher(doc, "mySearcher"),             ignoreClick: true, icon: "search",      },
             { title: "Files",           toolTip: "Files",           target: this.setupFilesystem(doc, "myFilesystem"),         ignoreClick: true, icon: "folder-open", },
             { title: "Tools",           toolTip: "Tools",           target: this.setupToolsBtnPanel(doc, "myTools"),           ignoreClick: true, icon: "wrench",      funcs: {hidden: "IsNoviceMode()"} },
-            { title: "Imports",         toolTip: "Imports ⌘I",     target: this.setupImportSidebar(doc, "myImports"),         ignoreClick: true, icon: "upload",      },
+            { title: "Imports",         toolTip: "Imports ⌘I",      target: this.setupImportSidebar(doc, "myImports"),         ignoreClick:false, icon: "upload",      },
             { title: "Closed",          toolTip: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), ignoreClick: true, icon: "archive",     },
             { title: "Shared",          toolTip: "Shared Docs",     target: Doc.MySharedDocs,                                  ignoreClick: true, icon: "users",       funcs: {badgeValue: badgeValue}},
-            { title: "Trails",          toolTip: "Trails ⌘R",      target: Doc.UserDoc(),                                     ignoreClick: true, icon: "pres-trail",  funcs: {target: getActiveDashTrails}},
+            { title: "Trails",          toolTip: "Trails ⌘R",       target: Doc.UserDoc(),                                     ignoreClick: true, icon: "pres-trail",  funcs: {target: getActiveDashTrails}},
             { title: "User Doc",        toolTip: "User Doc",        target: this.setupUserDocView(doc, "myUserDocView"),       ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} },
         ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(self)'}}));
     }
@@ -805,19 +805,17 @@ export class CurrentUserUtils {
         
         DocUtils.AssignDocField(doc, "mySharedDocs", opts => Docs.Create.TreeDocument([], opts, sharingDocumentId + "layout", sharingDocumentId), sharedDocOpts, undefined, sharedScripts);
         if (!Doc.GetProto(DocCast(doc.mySharedDocs)).data_dashboards) Doc.GetProto(DocCast(doc.mySharedDocs)).data_dashboards = new List<Doc>();
-        console.log(doc.mySharedDocs);
     }
 
     /// Import option on the left side button panel 
-    static setupImportSidebar(doc: Doc, field:string) {   
-        // PresElementBox.LayoutString('data')
+    static setupImportSidebar(doc: Doc, field:string) {
         const reqdOpts:DocumentOptions = {
-            title: "My Imports", _forceActive: true, ignoreClick: true, _layout_showTitle: "title", childLayoutString: ImportElementBox.LayoutString('data'),
-            _dragOnlyWithinContainer: true, _layout_hideContextMenu: true, childLimitHeight: 0,
+            title: "My Imports", _forceActive: true, _layout_showTitle: "title", childLayoutString: ImportElementBox.LayoutString('data'),
+            _dragOnlyWithinContainer: true, _layout_hideContextMenu: true, childLimitHeight: 0, onClickScriptDisable:"never",
             childDragAction: "copy", _layout_autoHeight: true, _yMargin: 50, _gridGap: 15, layout_boxShadow: "0 0", _lockedPosition: true, isSystem: true, _chromeHidden: true,
             dontRegisterView: true, layout_explainer: "This is where documents that are Imported into Dash will go."
         };
-        const myImports = DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.StackingDocument([], opts), reqdOpts);
+        const myImports = DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.MasonryDocument([], opts), reqdOpts, undefined, {onClick: "deselectAll()"});
     
         const reqdBtnOpts:DocumentOptions = { _forceActive: true, toolTip: "Import from computer",
             _width: 30, _height: 30, color: Colors.BLACK, _dragOnlyWithinContainer: true, _layout_hideContextMenu: true, title: "Import", btnType: ButtonType.ClickButton, 
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 0125331ec..4be9448b3 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -121,3 +121,6 @@ ScriptingGlobals.add(function SelectionManager_selectedDocType(type: string, exp
     let selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement());
     return selected?.type === type || selected?.type_collection === type || !type;
 });
+ScriptingGlobals.add(function deselectAll() {
+    SelectionManager.DeselectAll();
+});
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index bab07ac96..956dac555 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -911,7 +911,13 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
                                 height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px',
                             }}>
-                            <div className="documentDecorations-topbar" style={{ display: hideDeleteButton && hideTitle && hideOpenButton ? 'none' : undefined }} onPointerDown={this.onContainerDown}>
+                            <div
+                                className="documentDecorations-topbar"
+                                style={{
+                                    color: 'black',
+                                    display: hideDeleteButton && hideTitle && hideOpenButton ? 'none' : undefined,
+                                }}
+                                onPointerDown={this.onContainerDown}>
                                 {hideDeleteButton ? null : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
                                 {hideResizers || hideDeleteButton ? null : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
                                 {titleArea}
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 6f88f6727..22beb19de 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -8,7 +8,7 @@ import { Id } from '../../../fields/FieldSymbols';
 import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { ScriptField } from '../../../fields/ScriptField';
 import { NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, numberRange, returnEmptyString, setupMoveUpEvents } from '../../../Utils';
+import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { CompileScript } from '../../util/Scripting';
@@ -252,10 +252,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
-                    <div className={'optionPicker' + (selected === true ? ' active' : '')} onClick={this.toggleEmbedding}>
-                        Create Embedding
-                    </div>
-                    <div className={'optionPicker' + (selected === true ? ' active' : '')} onClick={this.deleteRow}>
+                    <div className={'optionPicker' + (selected === true ? ' active' : '')} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.deleteRow)}>
                         Delete
                     </div>
                 </div>
@@ -273,13 +270,16 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         const stackPad = showChrome ? `0px ${this.props.parent.xMargin}px` : `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px 0px ${this.props.parent.xMargin}px `;
         return this.collapsed ? null : (
             <div style={{ position: 'relative' }}>
+                {this.props.showHandle && this.props.parent.props.isContentActive() ? this.props.parent.columnDragger : null}
                 {showChrome ? (
                     <div
                         className="collectionStackingView-addDocumentButton"
-                        style={{
-                            //width: style.columnWidth / style.numGroupColumns,
-                            padding: `${NumCast(this.props.parent.layoutDoc._yPadding, this.props.parent.yMargin)}px 0px 0px 0px`,
-                        }}>
+                        style={
+                            {
+                                //width: style.columnWidth / style.numGroupColumns,
+                                //padding: `${NumCast(this.props.parent.layoutDoc._yPadding, this.props.parent.yMargin)}px 0px 0px 0px`,
+                            }
+                        }>
                         <EditableView GetValue={returnEmptyString} SetValue={this.addDocument} textCallback={this.textCallback} contents={'+ NEW'} />
                     </div>
                 ) : null}
@@ -288,12 +288,12 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                     ref={this._contRef}
                     style={{
                         padding: stackPad,
+                        minHeight: this.props.showHandle && this.props.parent.props.isContentActive() ? '10px' : undefined,
                         width: this.props.parent.NodeWidth,
                         gridGap: this.props.parent.gridGap,
                         gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ''),
                     }}>
                     {this.props.parent.children(this.props.docList)}
-                    {this.props.showHandle && this.props.parent.props.isContentActive() ? this.props.parent.columnDragger : null}
                 </div>
             </div>
         );
@@ -313,23 +313,33 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                     onPointerDown={this.headerDown}
                     title={evContents === `NO ${key.toUpperCase()} VALUE` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
                     style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this.color : 'lightgrey' }}>
-                    {noChrome ? evContents : editableHeaderView}
+                    {noChrome ? evContents : <div>{editableHeaderView}</div>}
                     {noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
                         <div className="collectionStackingView-sectionColor">
-                            <button className="collectionStackingView-sectionColorButton" onClick={action(e => (this._paletteOn = !this._paletteOn))}>
+                            <button
+                                className="collectionStackingView-sectionColorButton"
+                                onPointerDown={e =>
+                                    setupMoveUpEvents(
+                                        this,
+                                        e,
+                                        returnFalse,
+                                        emptyFunction,
+                                        action(e => (this._paletteOn = !this._paletteOn))
+                                    )
+                                }>
                                 <FontAwesomeIcon icon="palette" size="lg" />
                             </button>
                             {this._paletteOn ? this.renderColorPicker() : null}
                         </div>
                     )}
                     {noChrome ? null : (
-                        <button className="collectionStackingView-sectionDelete" onClick={noChrome ? undefined : this.collapseSection}>
+                        <button className="collectionStackingView-sectionDelete" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, noChrome ? emptyFunction : this.collapseSection)}>
                             <FontAwesomeIcon icon={this.collapsed ? 'chevron-down' : 'chevron-up'} size="lg" />
                         </button>
                     )}
                     {noChrome || evContents === `NO  ${key.toUpperCase()} VALUE` ? null : (
-                        <div className="collectionStackingView-sectionOptions">
-                            <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderMenu()}>
+                        <div className="collectionStackingView-sectionOptions" onPointerDown={e => e.stopPropagation()}>
+                            <Flyout anchorPoint={anchorPoints.RIGHT_TOP} content={this.renderMenu()}>
                                 <button className="collectionStackingView-sectionOptionButton">
                                     <FontAwesomeIcon icon="ellipsis-v" size="lg" />
                                 </button>
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 99a68e94b..255bc3889 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -128,6 +128,7 @@
         height: 15;
         position: absolute;
         margin-left: -5;
+        z-index: 10;
     }
 
     // Documents in stacking view
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 805002452..e964d41a8 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,7 +1,7 @@
 import React = require('react');
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { CursorProperty } from 'csstype';
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, Opt } from '../../../fields/Doc';
 import { DocData, Height, Width } from '../../../fields/DocSymbols';
@@ -11,7 +11,7 @@ import { listSpec } from '../../../fields/Schema';
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
+import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { CollectionViewType } from '../../documents/DocumentTypes';
 import { DragManager, dropActionType } from '../../util/DragManager';
@@ -31,7 +31,6 @@ import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow';
 import './CollectionStackingView.scss';
 import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn';
 import { CollectionSubView } from './CollectionSubView';
-import { Colors } from '../global/globalEnums';
 const _global = (window /* browser */ || global) /* node */ as any;
 
 export type collectionStackingViewProps = {
@@ -308,19 +307,18 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             ? false
             : undefined;
     isChildButtonContentActive = () => (this.props.childDocumentsActive?.() === false || this.rootDoc.childDocumentsActive === false ? false : undefined);
+    @observable docRefs = new ObservableMap<Doc, DocumentView>();
     // this is what renders the document that you see on the screen
     // called in Children: this actually adds a document to our children list
     getDisplayDoc(doc: Doc, width: () => number, count: number) {
         const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.DataDoc;
         const height = () => this.getDocHeight(doc);
 
-        let dref: Opt<DocumentView>;
-        const stackedDocTransform = () => this.getDocTransform(doc, dref);
+        const stackedDocTransform = () => this.getDocTransform(doc);
         this._docXfs.push({ stackedDocTransform, width, height });
-        //DocumentView is how the node will be rendered
         return count > this._renderCount ? null : (
             <DocumentView
-                ref={r => (dref = r || undefined)}
+                ref={action((r: DocumentView) => r?.ContentDiv && this.docRefs.set(doc, r))}
                 Document={doc}
                 DataDoc={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)}
                 renderDepth={this.props.renderDepth + 1}
@@ -368,9 +366,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         );
     }
 
-    getDocTransform(doc: Doc, dref?: DocumentView) {
-        const y = this._scroll; // required for document decorations to update when the text box container is scrolled
-        const { scale, translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined);
+    getDocTransform(doc: Doc) {
+        const dref = this.docRefs.get(doc);
+        this._scroll; // must be referenced for document decorations to update when the text box container is scrolled
+        const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv);
         // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform.  so we have to subtract that off
         return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale);
     }
@@ -423,7 +422,11 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
 
     @computed get columnDragger() {
         return (
-            <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }}>
+            <div
+                className="collectionStackingView-columnDragger"
+                onPointerDown={this.columnDividerDown}
+                ref={this._draggerRef}
+                style={{ cursor: this._cursor, color: StrCast(Doc.UserDoc().userColor), left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }}>
                 <FontAwesomeIcon icon={'arrows-alt-h'} />
             </div>
         );
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index a04f640df..1098b56c2 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -795,6 +795,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         const folderOp = this.childDocs?.length ? [makeFolder] : [];
         const openEmbedding = { script: ScriptField.MakeFunction(`openDoc(getEmbedding(self), "${OpenWhere.addRight}")`)!, icon: 'copy', label: 'Open New Embedding' };
         const focusDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, icon: 'eye', label: 'Focus or Open' };
+        const reopenDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, icon: 'eye', label: 'Reopen' };
         return [
             ...(this.props.contextMenuItems ?? []).filter(mi => (!mi.filter ? true : mi.filter.script.run({ doc: this.doc })?.result)),
             ...(this.doc.isFolder
@@ -805,6 +806,8 @@ export class TreeView extends React.Component<TreeViewProps> {
                 ? [openEmbedding, makeFolder]
                 : this.doc._type_collection === CollectionViewType.Docking
                 ? []
+                : this.props.treeView.rootDoc === Doc.MyRecentlyClosed
+                ? [reopenDoc]
                 : [openEmbedding, focusDoc]),
         ];
     };
@@ -1002,13 +1005,13 @@ export class TreeView extends React.Component<TreeViewProps> {
                     onPointerDown={this.ignoreEvent}
                     onPointerEnter={this.onPointerEnter}
                     onPointerLeave={this.onPointerLeave}>
-                    {contents}
                     <div
-                        className={`treeView-background`}
+                        className="treeView-background"
                         style={{
                             background: StrCast(Doc.UserDoc().userColor),
                         }}
                     />
+                    {contents}
                 </div>
                 {this.renderBorder}
             </>
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 7e8eef0a5..2d8663c9c 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -18,7 +18,6 @@ import { SearchBox } from '../search/SearchBox';
 import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo';
 import { YoutubeBox } from './../../apis/youtube/YoutubeBox';
 import { AudioBox } from './AudioBox';
-import { FontIconBox } from './FontIconBox/FontIconBox';
 import { ColorBox } from './ColorBox';
 import { ComparisonBox } from './ComparisonBox';
 import { DataVizBox } from './DataVizBox/DataVizBox';
@@ -26,9 +25,11 @@ import { DocumentViewProps } from './DocumentView';
 import './DocumentView.scss';
 import { EquationBox } from './EquationBox';
 import { FieldView, FieldViewProps } from './FieldView';
+import { FontIconBox } from './FontIconBox/FontIconBox';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { FunctionPlotBox } from './FunctionPlotBox';
 import { ImageBox } from './ImageBox';
+import { ImportElementBox } from './importBox/ImportElementBox';
 import { KeyValueBox } from './KeyValueBox';
 import { LabelBox } from './LabelBox';
 import { LinkAnchorBox } from './LinkAnchorBox';
@@ -269,6 +270,7 @@ export class DocumentContentsView extends React.Component<
                     LoadingBox,
                     PhysicsSimulationBox,
                     SchemaRowBox,
+                    ImportElementBox,
                 }}
                 bindings={bindings}
                 jsx={layoutFrame}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 66352678c..977a64c2c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -332,8 +332,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         return (
             DocumentView.LongPress ||
             onScriptDisable === 'always' ||
-            (onScriptDisable !== 'never' && (this.rootSelected() || this.props.isSelected())) ||
-            this._componentView?.isAnyChildContentActive?.()
+            (onScriptDisable !== 'never' && (this.rootSelected() || this._componentView?.isAnyChildContentActive?.()))
         );
     }
     @computed get onClickHandler() {
@@ -800,7 +799,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         }
         const constantItems: ContextMenuProps[] = [];
         if (!Doc.IsSystem(this.rootDoc)) {
-            constantItems.push({ description: 'Export as Zip file', icon: 'download', event: async () => Doc.Zip(this.props.Document) });
+            constantItems.push({ description: 'Zip Export', icon: 'download', event: async () => Doc.Zip(this.props.Document) });
             (this.rootDoc._type_collection !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this.props.DocumentView()), icon: 'users' });
             if (this.props.removeDocument && Doc.ActiveDashboard !== this.props.Document) {
                 // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
@@ -875,13 +874,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         // undefined - it is not active, but it should be responsive to actions that might active it or its contents (eg clicking)
         return this.props.isContentActive() === false || this.props.pointerEvents?.() === 'none' || (this.rootDoc.pointerEvents === 'none' && !StrCast(this.props.LayoutTemplateString).includes(KeyValueBox.name))
             ? false
-            : Doc.ActiveTool !== InkTool.None ||
-              SnappingManager.GetIsDragging() ||
-              this.rootSelected() ||
-              this.rootDoc.forceActive ||
-              this.props.isSelected(outsideReaction) ||
-              this._componentView?.isAnyChildContentActive?.() ||
-              this.props.isContentActive()
+            : Doc.ActiveTool !== InkTool.None || SnappingManager.GetIsDragging() || this.rootSelected() || this.rootDoc.forceActive || this._componentView?.isAnyChildContentActive?.() || this.props.isContentActive()
             ? true
             : undefined;
     };
diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx
index a5d21cc8e..58f0b29e4 100644
--- a/src/client/views/nodes/importBox/ImportElementBox.tsx
+++ b/src/client/views/nodes/importBox/ImportElementBox.tsx
@@ -1,13 +1,13 @@
-import { observer } from "mobx-react";
-import { ViewBoxBaseComponent } from "../../DocComponent";
-import { FieldView, FieldViewProps } from "../FieldView";
-import { computed } from "mobx";
-import { Id } from "../../../../fields/FieldSymbols";
-import React from "react";
-import { EditableView } from "../../EditableView";
-import { DocListCast } from "../../../../fields/Doc";
-import { StrCast } from "../../../../fields/Types";
-
+import { computed } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc } from '../../../../fields/Doc';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue } from '../../../../Utils';
+import { Transform } from '../../../util/Transform';
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { DefaultStyleProvider } from '../../StyleProvider';
+import { DocumentView, DocumentViewInternal } from '../DocumentView';
+import { FieldView, FieldViewProps } from '../FieldView';
+import React = require('react');
 
 @observer
 export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
@@ -15,56 +15,24 @@ export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
         return FieldView.LayoutString(ImportElementBox, fieldKey);
     }
 
-    private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
-    private _dragRef: React.RefObject<HTMLDivElement> = React.createRef();
-    private _titleRef: React.RefObject<EditableView> = React.createRef();
-
-    @computed importBoxVoew() {
-        return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as PresBox;
-    }
-    
-    @computed get indexInPres() {
-        return DocListCast(this.presBox?.[StrCast(this.presBox.presFieldKey, 'data')]).indexOf(this.rootDoc);
+    screenToLocalXf = () => this.props.ScreenToLocalTransform().scale(1 * (this.props.NativeDimScaling?.() || 1));
+    @computed get mainItem() {
+        return (
+            <div style={{ backgroundColor: 'pink' }}>
+                <DocumentView
+                    {...this.props} //
+                    LayoutTemplateString={undefined}
+                    Document={this.rootDoc}
+                    isContentActive={returnFalse}
+                    DataDoc={undefined}
+                    addDocument={returnFalse}
+                    ScreenToLocalTransform={this.screenToLocalXf}
+                    hideResizeHandles={true}
+                />
+            </div>
+        );
     }
-    
-    @computed get presBox() {
-        return this.props.DocumentView?.().props.docViewPath().lastElement()?.rootDoc;
+    render() {
+        return !(this.rootDoc instanceof Doc) ? null : this.mainItem;
     }
-
-    // @computed get selectedArray() {
-    //     return this.presBoxView?.selectedArray;
-    // }
-
-@computed get mainItem() {
-    const isCurrent: boolean = this.presBox?._itemIndex === this.indexInPres;
-    //const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false;
-  //  const activeItem: Doc = this.rootDoc;
-
-    return(
-        <div
-            className = {`presItem-container`}
-            // key={this.props.Document[Id] + this.indexInPres}
-            style = {{backgroundColor: 'pink'}}
-            
-        >
-            <div
-                ref = {this._dragRef}
-                className = {`presItem-slide ${isCurrent ? 'active' : ''}`}
-                style = {{
-                    backgroundColor: 'green'
-                }}>
-                    <div
-                        className="presItem-number"
-                        title = "select without navigation"
-                    
-                    >
-                         {/* <EditableView ref={this._titleRef} oneLine={true} editing={!isSelected ? false : undefined} contents={activeItem.title} overflow={'ellipsis'} GetValue={() => StrCast(activeItem.title)} SetValue={this.onSetValue} /> */}
-
-                    </div>
-            </div>
-
-        </div>
-    )
 }
-
-}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

