From 0eb9d37a9dd1a6539f331f953d5f20c761d5f940 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 17 Aug 2023 10:00:10 -0400
Subject: fixed brushing of pinned viewports for chrome to not flash. converted
 pres<Property> to config_<property> and treeView<Property> to
 treeView_Property.  fixed text toolbar to show/set text properties based on
 insertion point.

---
 src/client/views/collections/TreeView.tsx | 90 +++++++++++++++----------------
 1 file changed, 45 insertions(+), 45 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 25a547066..27f9ebc49 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -87,8 +87,8 @@ export enum TreeSort {
  * Renders a treeView of a collection of documents
  *
  * special fields:
- * treeViewOpen : flag denoting whether the documents sub-tree (contents) is visible or hidden
- * treeViewExpandedView : name of field whose contents are being displayed as the document's subtree
+ * treeView_Open : flag denoting whether the documents sub-tree (contents) is visible or hidden
+ * treeView_ExpandedView : name of field whose contents are being displayed as the document's subtree
  */
 @observer
 export class TreeView extends React.Component<TreeViewProps> {
@@ -104,16 +104,16 @@ export class TreeView extends React.Component<TreeViewProps> {
     private _treedropDisposer?: DragManager.DragDropDisposer;
 
     get treeViewOpenIsTransient() {
-        return this.props.treeView.doc.treeViewOpenIsTransient || Doc.IsDataProto(this.doc);
+        return this.props.treeView.doc.treeView_OpenIsTransient || Doc.IsDataProto(this.doc);
     }
     set treeViewOpen(c: boolean) {
         if (this.treeViewOpenIsTransient) this._transientOpenState = c;
         else {
-            this.doc.treeViewOpen = c;
+            this.doc.treeView_Open = c;
             this._transientOpenState = false;
         }
     }
-    @observable _transientOpenState = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
+    @observable _transientOpenState = false; // override of the treeView_Open field allowing the display state to be independent of the document's state
     @observable _editTitle: boolean = false;
     @observable _dref: DocumentView | undefined | null;
     get displayName() {
@@ -132,29 +132,29 @@ export class TreeView extends React.Component<TreeViewProps> {
             ? this.fieldKey
             : Doc.noviceMode
             ? 'layout'
-            : StrCast(this.props.treeView.doc.treeViewExpandedView, 'fields');
+            : StrCast(this.props.treeView.doc.treeView_ExpandedView, 'fields');
     }
 
     @computed get doc() {
         return this.props.document;
     }
     @computed get treeViewOpen() {
-        return (!this.treeViewOpenIsTransient && Doc.GetT(this.doc, 'treeViewOpen', 'boolean', true)) || this._transientOpenState;
+        return (!this.treeViewOpenIsTransient && Doc.GetT(this.doc, 'treeView_Open', 'boolean', true)) || this._transientOpenState;
     }
     @computed get treeViewExpandedView() {
-        return this.validExpandViewTypes.includes(StrCast(this.doc.treeViewExpandedView)) ? StrCast(this.doc.treeViewExpandedView) : this.defaultExpandedView;
+        return this.validExpandViewTypes.includes(StrCast(this.doc.treeView_ExpandedView)) ? StrCast(this.doc.treeView_ExpandedView) : this.defaultExpandedView;
     }
     @computed get MAX_EMBED_HEIGHT() {
         return NumCast(this.props.treeViewParent.maxEmbedHeight, 200);
     }
     @computed get dataDoc() {
-        return this.props.document.treeViewChildrenOnRoot ? this.doc : this.doc[DocData];
+        return this.props.document.treeView_ChildrenOnRoot ? this.doc : this.doc[DocData];
     }
     @computed get layoutDoc() {
         return Doc.Layout(this.doc);
     }
     @computed get fieldKey() {
-        return StrCast(this.doc._treeViewFieldKey, Doc.LayoutFieldKey(this.doc));
+        return StrCast(this.doc._treeView_FieldKey, Doc.LayoutFieldKey(this.doc));
     }
     @computed get childDocs() {
         return this.childDocList(this.fieldKey);
@@ -308,13 +308,13 @@ export class TreeView extends React.Component<TreeViewProps> {
         const bullet = Docs.Create.TextDocument('', {
             layout: CollectionView.LayoutString('data'),
             title: '-title-',
-            treeViewExpandedViewLock: true,
-            treeViewExpandedView: 'data',
+            treeView_ExpandedViewLock: true,
+            treeView_ExpandedView: 'data',
             _type_collection: CollectionViewType.Tree,
             layout_hideLinkButton: true,
             _layout_showSidebar: true,
             _layout_fitWidth: true,
-            treeViewType: TreeViewType.outline,
+            treeView_Type: TreeViewType.outline,
             x: 0,
             y: 0,
             _xMargin: 0,
@@ -395,7 +395,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         };
         const addDoc = inside ? localAdd : parentAddDoc;
         const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same') && moveDocument;
-        const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.treeViewParent)?.treeViewFreezeChildren).includes('add')) || forceAdd;
+        const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.treeViewParent)?.treeView_FreezeChildren).includes('add')) || forceAdd;
         if (canAdd) {
             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);
@@ -438,7 +438,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
 
         for (const key of Object.keys(ids).slice().sort()) {
-            if (this.props.skipFields?.includes(key) || key === 'title' || key === 'treeViewOpen') continue;
+            if (this.props.skipFields?.includes(key) || key === 'title' || key === 'treeView_Open') continue;
             const contents = doc[key];
             let contentElement: (JSX.Element | null)[] | JSX.Element = [];
 
@@ -538,7 +538,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         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 } }) ?? {};
         if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) {
-            const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
+            const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.None);
             const sortKeys = Object.keys(sortings);
             const curSortIndex = Math.max(
                 0,
@@ -550,7 +550,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
                 // if there's a sort ordering specified that can be modified on drop (eg, zorder can be modified, alphabetical can't),
                 // then the modification would be done here
-                const ordering = StrCast(this.doc.treeViewSortCriterion);
+                const ordering = StrCast(this.doc.treeView_SortCriterion);
                 if (ordering === TreeSort.Zindex) {
                     const docs = TreeView.sortDocs(this.childDocs || ([] as Doc[]), ordering);
                     doc.zIndex = addBefore ? NumCast(addBefore.zIndex) + (before ? -0.5 : 0.5) : 1000;
@@ -590,7 +590,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                                 }}
                                 onClick={undoable(e => {
                                     if (this.props.isContentActive() && Math.abs(e.clientX - downX) < 3 && Math.abs(e.clientY - downY) < 3) {
-                                        !this.props.treeView.outlineMode && (this.doc.treeViewSortCriterion = sortKeys[(curSortIndex + 1) % sortKeys.length]);
+                                        !this.props.treeView.outlineMode && (this.doc.treeView_SortCriterion = sortKeys[(curSortIndex + 1) % sortKeys.length]);
                                         e.stopPropagation();
                                     }
                                 }, 'sort order')}
@@ -601,7 +601,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         style={{ cursor: 'inherit' }}
                         key={expandKey + 'more'}
                         title="click to change sort order"
-                        className={''} //this.doc.treeViewHideTitle ? 'no-indent' : ''}
+                        className={''} //this.doc.treeView_HideTitle ? 'no-indent' : ''}
                         onPointerDown={e => {
                             downX = e.clientX;
                             downY = e.clientY;
@@ -609,7 +609,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         }}
                         onClick={undoable(e => {
                             if (this.props.isContentActive() && Math.abs(e.clientX - downX) < 3 && Math.abs(e.clientY - downY) < 3) {
-                                !this.props.treeView.outlineMode && (this.doc.treeViewSortCriterion = sortKeys[(curSortIndex + 1) % sortKeys.length]);
+                                !this.props.treeView.outlineMode && (this.doc.treeView_SortCriterion = sortKeys[(curSortIndex + 1) % sortKeys.length]);
                                 e.stopPropagation();
                             }
                         }, 'sort order')}>
@@ -683,7 +683,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 {
                     this: this.doc.isTemplateForField && this.props.dataDoc ? this.props.dataDoc : this.doc,
                     heading: this.props.treeViewParent.title,
-                    checked: this.doc.treeViewChecked === 'check' ? 'x' : this.doc.treeViewChecked === 'x' ? 'remove' : 'check',
+                    checked: this.doc.treeView_Checked === 'check' ? 'x' : this.doc.treeView_Checked === 'x' ? 'remove' : 'check',
                     containingTreeView: this.props.treeView.props.Document,
                 },
                 console.log
@@ -698,7 +698,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         TraceMobx();
         const iconType = this.props.treeView.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':open' : !this.childDocs.length ? ':empty' : '')) || 'question';
         const color = StrCast(Doc.UserDoc().userColor);
-        const checked = this.onCheckedClick ? this.doc.treeViewChecked ?? 'unchecked' : undefined;
+        const checked = this.onCheckedClick ? this.doc.treeView_Checked ?? 'unchecked' : undefined;
         return (
             <div
                 className={`bullet${this.props.treeView.outlineMode ? '-outline' : ''}`}
@@ -748,9 +748,9 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
     @action
     expandNextviewType = () => {
-        if (this.treeViewOpen && !this.doc.isFolder && !this.props.treeView.outlineMode && !this.doc.treeViewExpandedViewLock) {
+        if (this.treeViewOpen && !this.doc.isFolder && !this.props.treeView.outlineMode && !this.doc.treeView_ExpandedViewLock) {
             const next = (modes: any[]) => modes[(modes.indexOf(StrCast(this.treeViewExpandedView)) + 1) % modes.length];
-            this.doc.treeViewExpandedView = next(this.validExpandViewTypes);
+            this.doc.treeView_ExpandedView = next(this.validExpandViewTypes);
         }
         this.treeViewOpen = true;
     };
@@ -759,7 +759,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed get titleButtons() {
         const customHeaderButtons = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Decorations);
         const color = StrCast(Doc.UserDoc().userColor);
-        return this.props.treeViewHideHeaderFields() || this.doc.treeViewHideHeaderFields ? null : (
+        return this.props.treeViewHideHeaderFields() || this.doc.treeView_HideHeaderFields ? null : (
             <>
                 {customHeaderButtons} {/* e.g.,. hide button is set by dashboardStyleProvider */}
                 <IconButton
@@ -771,7 +771,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         e.stopPropagation();
                     }}
                 />
-                {Doc.noviceMode ? null : this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? null : (
+                {Doc.noviceMode ? null : this.doc.treeView_ExpandedViewLock || Doc.IsSystem(this.doc) ? null : (
                     <span className="collectionTreeView-keyHeader" title="type of expanded data" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
                         {this.treeViewExpandedView}
                     </span>
@@ -815,7 +815,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
     onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!);
 
-    onChildDoubleClick = () => ScriptCast(this.props.treeView.Document.treeViewChildDoubleClick, !this.props.treeView.outlineMode ? this._openScript?.() : null);
+    onChildDoubleClick = () => ScriptCast(this.props.treeView.Document.treeView_ChildDoubleClick, !this.props.treeView.outlineMode ? this._openScript?.() : null);
 
     refocus = () => this.props.treeView.props.focus(this.props.treeView.props.Document, {});
     ignoreEvent = (e: any) => {
@@ -861,7 +861,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
     };
     onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
-        if (this.doc.treeViewHideHeader || (this.doc.treeViewHideHeaderIfTemplate && this.props.treeView.props.childLayoutTemplate?.()) || this.props.treeView.outlineMode) {
+        if (this.doc.treeView_HideHeader || (this.doc.treeView_HideHeaderIfTemplate && this.props.treeView.props.childLayoutTemplate?.()) || this.props.treeView.outlineMode) {
             switch (e.key) {
                 case 'Tab':
                     e.stopPropagation?.();
@@ -1068,7 +1068,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
     // renders the text version of a document as the header.  This is used in the file system mode and in other vanilla tree views.
     @computed get renderTitleAsHeader() {
-        return this.props.treeView.Document.treeViewHideUnrendered && this.doc.layout_unrendered && !this.doc.treeViewFieldKey ? (
+        return this.props.treeView.Document.treeView_HideUnrendered && this.doc.layout_unrendered && !this.doc.treeView_FieldKey ? (
             <div></div>
         ) : (
             <>
@@ -1089,7 +1089,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     };
 
     @computed get renderBorder() {
-        const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
+        const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.None);
         const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; label: string } };
         return (
             <div className={`treeView-border${this.props.treeView.outlineMode ? TreeViewType.outline : ''}`} style={{ borderColor: sortings[sorting]?.color }}>
@@ -1109,7 +1109,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
     render() {
         TraceMobx();
-        const hideTitle = this.doc.treeViewHideHeader || (this.doc.treeViewHideHeaderIfTemplate && this.props.treeView.props.childLayoutTemplate?.()) || this.props.treeView.outlineMode;
+        const hideTitle = this.doc.treeView_HideHeader || (this.doc.treeView_HideHeaderIfTemplate && this.props.treeView.props.childLayoutTemplate?.()) || this.props.treeView.outlineMode;
         return this.props.renderedIds?.indexOf(this.doc[Id]) !== -1 ? (
             '<' + this.doc.title + '>' // just print the title of documents we've previously rendered in this hierarchical path to avoid cycles
         ) : (
@@ -1121,9 +1121,9 @@ export class TreeView extends React.Component<TreeViewProps> {
                 // onKeyDown={this.onKeyDown}
             >
                 <li className="collection-child">
-                    {hideTitle && this.doc.type !== DocumentType.RTF && !this.doc.treeViewRenderAsBulletHeader // should test for prop 'treeViewRenderDocWithBulletAsHeader"
+                    {hideTitle && this.doc.type !== DocumentType.RTF && !this.doc.treeView_RenderAsBulletHeader // should test for prop 'treeView_RenderDocWithBulletAsHeader"
                         ? this.renderEmbeddedDocument(false, returnFalse)
-                        : this.renderBulletHeader(hideTitle ? this.renderDocumentAsHeader(!this.doc.treeViewRenderAsBulletHeader) : this.renderTitleAsHeader, this._editTitle)}
+                        : this.renderBulletHeader(hideTitle ? this.renderDocumentAsHeader(!this.doc.treeView_RenderAsBulletHeader) : this.renderTitleAsHeader, this._editTitle)}
                 </li>
             </div>
         );
@@ -1162,7 +1162,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         childDocs: Doc[],
         treeView: CollectionTreeView,
         parentTreeView: CollectionTreeView | TreeView | undefined,
-        treeViewParent: Doc,
+        treeView_Parent: Doc,
         dataDoc: Doc | undefined,
         parentCollectionDoc: Doc | undefined,
         containerPrevSibling: Doc | undefined,
@@ -1176,7 +1176,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         isContentActive: (outsideReaction?: boolean) => boolean,
         panelWidth: () => number,
         renderDepth: number,
-        treeViewHideHeaderFields: () => boolean,
+        treeView_HideHeaderFields: () => boolean,
         renderedIds: string[],
         onCheckedClick: undefined | (() => ScriptField),
         onChildClick: undefined | (() => ScriptField),
@@ -1193,19 +1193,19 @@ export class TreeView extends React.Component<TreeViewProps> {
         hierarchyIndex?: number[],
         renderCount?: number
     ) {
-        const viewSpecScript = Cast(treeViewParent.viewSpecScript, ScriptField);
+        const viewSpecScript = Cast(treeView_Parent.viewSpecScript, ScriptField);
         if (viewSpecScript) {
             childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
         }
 
-        const docs = TreeView.sortDocs(childDocs, StrCast(treeViewParent.treeViewSortCriterion, TreeSort.None));
+        const docs = TreeView.sortDocs(childDocs, StrCast(treeView_Parent.treeView_SortCriterion, TreeSort.None));
         const rowWidth = () => panelWidth() - treeBulletWidth() * (treeView.props.NativeDimScaling?.() || 1);
-        const treeViewRefs = new Map<Doc, TreeView | undefined>();
+        const treeView_Refs = new Map<Doc, TreeView | undefined>();
         return docs
             .filter(child => child instanceof Doc)
             .map((child, i) => {
                 if (renderCount && i > renderCount) return null;
-                const pair = Doc.GetLayoutDataDocPair(treeViewParent, dataDoc, child);
+                const pair = Doc.GetLayoutDataDocPair(treeView_Parent, dataDoc, child);
                 if (!pair.layout || pair.data instanceof Promise) {
                     return null;
                 }
@@ -1218,11 +1218,11 @@ export class TreeView extends React.Component<TreeViewProps> {
                         FormattedTextBox.SelectOnLoad = child[Id];
                         TreeView._editTitleOnLoad = editTitle ? { id: child[Id], parent } : undefined;
                         Doc.AddDocToList(newParent, fieldKey, child, addAfter, false);
-                        newParent.treeViewOpen = true;
+                        newParent.treeView_Open = true;
                         Doc.SetContainer(child, treeView.Document);
                     }
                 };
-                const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeViewRefs.get(docs[i - 1]));
+                const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeView_Refs.get(docs[i - 1]));
                 const outdent = !parentCollectionDoc ? undefined : (editTitle: boolean) => dentDoc(editTitle, parentCollectionDoc, containerPrevSibling, parentTreeView instanceof TreeView ? parentTreeView.props.parentTreeView : undefined);
                 const addDocument = (doc: Doc | Doc[], annotationKey?: string, relativeTo?: Doc, before?: boolean) => add(doc, relativeTo ?? docs[i], before !== undefined ? before : false);
                 const childLayout = Doc.Layout(pair.layout);
@@ -1233,10 +1233,10 @@ export class TreeView extends React.Component<TreeViewProps> {
                 return (
                     <TreeView
                         key={child[Id]}
-                        ref={r => treeViewRefs.set(child, r ? r : undefined)}
+                        ref={r => treeView_Refs.set(child, r ? r : undefined)}
                         document={pair.layout}
                         dataDoc={pair.data}
-                        treeViewParent={treeViewParent}
+                        treeViewParent={treeView_Parent}
                         prevSibling={docs[i]}
                         // TODO: [AL] add these
                         hierarchyIndex={hierarchyIndex ? [...hierarchyIndex, i + 1] : undefined}
@@ -1248,7 +1248,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         onCheckedClick={onCheckedClick}
                         onChildClick={onChildClick}
                         renderDepth={renderDepth}
-                        removeDoc={StrCast(treeViewParent.treeViewFreezeChildren).includes('remove') ? undefined : remove}
+                        removeDoc={StrCast(treeView_Parent.treeView_FreezeChildren).includes('remove') ? undefined : remove}
                         addDocument={addDocument}
                         styleProvider={styleProvider}
                         panelWidth={rowWidth}
@@ -1259,7 +1259,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         addDocTab={addDocTab}
                         ScreenToLocalTransform={screenToLocalXf}
                         isContentActive={isContentActive}
-                        treeViewHideHeaderFields={treeViewHideHeaderFields}
+                        treeViewHideHeaderFields={treeView_HideHeaderFields}
                         renderedIds={renderedIds}
                         skipFields={skipFields}
                         firstLevel={firstLevel}
-- 
cgit v1.2.3-70-g09d2


From ad6e2e0844947f54a11b73f25b118aafabbf8b49 Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Tue, 22 Aug 2023 14:35:14 -0400
Subject: added tooltips for tree view sorting.  added close buttons for header
 bar.and added new tabs to header bar.  fixed rtf markup startup error.

---
 src/client/util/RTFMarkup.tsx                      |  2 +-
 src/client/views/StyleProvider.tsx                 |  9 ++++----
 .../views/collections/CollectionDockingView.tsx    |  2 ++
 src/client/views/collections/TreeView.tsx          | 27 +++++++++++-----------
 .../CollectionMulticolumnView.scss                 |  6 +++++
 .../CollectionMulticolumnView.tsx                  |  7 +++++-
 6 files changed, 33 insertions(+), 20 deletions(-)

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

diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index afc880a7b..a0fc617ab 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -31,7 +31,7 @@ export class RTFMarkup extends React.Component<{}> {
      */
     @computed get cheatSheet() {
         return (
-            <div style={{ background: SettingsManager.Instance.userBackgroundColor, color: SettingsManager.Instance.userColor, textAlign: 'initial', height: '100%' }}>
+            <div style={{ background: SettingsManager.Instance?.userBackgroundColor, color: SettingsManager.Instance?.userColor, textAlign: 'initial', height: '100%' }}>
                 <p>
                     <b style={{ fontSize: 'larger' }}>{`wiki:phrase`}</b>
                     {` display wikipedia page for entered text (terminate with carriage return)`}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index c2dcf071d..24a269927 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -109,10 +109,10 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
             return Doc.toIcon(doc, isEmpty ? undefined : isOpen);
         case StyleProp.TreeViewSortings:
             const allSorts: { [key: string]: { color: string; icon: JSX.Element | string } | undefined } = {};
-            allSorts[TreeSort.Down] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
-            allSorts[TreeSort.Up] = { color: 'crimson', icon: <BsArrowUp/> };
+            allSorts[TreeSort.AlphaDown] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
+            allSorts[TreeSort.AlphaUp] = { color: 'crimson', icon: <BsArrowUp/> };
             if (doc?._type_collection === CollectionViewType.Freeform) allSorts[TreeSort.Zindex] = { color: 'green', icon: 'Z' };
-            allSorts[TreeSort.None] = { color: 'darkgray', icon: <BsArrowDownUp/> };
+            allSorts[TreeSort.WhenAdded] = { color: 'darkgray', icon: <BsArrowDownUp/> };
             return allSorts;
         case StyleProp.Highlighting:
             if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;            
@@ -166,8 +166,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
             if (docColor) return docColor;
             const docView = props?.DocumentView?.();
             const backColor = backgroundCol() || docView?.props.styleProvider?.(docView.props.treeViewDoc, docView.props, StyleProp.BackgroundColor);
-            if (!backColor) return undefined;
-            return lightOrDark(backColor);
+            return backColor ? lightOrDark(backColor) : undefined;
         case StyleProp.BorderRounding:
             return StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : ''));
         case StyleProp.BorderPath:
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 0052c4196..95f88f14e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -498,6 +498,7 @@ export class CollectionDockingView extends CollectionSubView() {
                     _layout_fitWidth: true,
                     title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`,
                 });
+                Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd);
                 inheritParentAcls(this.rootDoc, docToAdd, false);
                 CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
             }
@@ -541,6 +542,7 @@ export class CollectionDockingView extends CollectionSubView() {
                             _freeform_backgroundGrid: true,
                             title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`,
                         });
+                        Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd);
                         inheritParentAcls(this.dataDoc, docToAdd, false);
                         CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
                     }
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 27f9ebc49..3402a8c8d 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -78,10 +78,10 @@ const treeBulletWidth = function () {
 };
 
 export enum TreeSort {
-    Up = 'up',
-    Down = 'down',
-    Zindex = 'z',
-    None = 'none',
+    AlphaUp = 'alphabetical from z',
+    AlphaDown = 'alphabetical from A',
+    Zindex = 'by Z index',
+    WhenAdded = 'when added',
 }
 /**
  * Renders a treeView of a collection of documents
@@ -538,7 +538,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         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 } }) ?? {};
         if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) {
-            const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.None);
+            const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.WhenAdded);
             const sortKeys = Object.keys(sortings);
             const curSortIndex = Math.max(
                 0,
@@ -578,10 +578,11 @@ export class TreeView extends React.Component<TreeViewProps> {
             return (
                 <div>
                     {!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : (
-                        <div className={'treeView-sorting'}>
+                        <div className='treeView-sorting'>
                             <IconButton
                                 color={sortings[sorting]?.color}
                                 size={Size.XSMALL}
+                                tooltip={`Sorted by : ${this.doc.treeView_SortCriterion}. click to cycle`}
                                 icon={sortings[sorting]?.icon}
                                 onPointerDown={e => {
                                     downX = e.clientX;
@@ -600,8 +601,8 @@ export class TreeView extends React.Component<TreeViewProps> {
                     <ul
                         style={{ cursor: 'inherit' }}
                         key={expandKey + 'more'}
-                        title="click to change sort order"
-                        className={''} //this.doc.treeView_HideTitle ? 'no-indent' : ''}
+                        title={`Sorted by : ${this.doc.treeView_SortCriterion}. click to cycle`}
+                        className='' //this.doc.treeView_HideTitle ? 'no-indent' : ''}
                         onPointerDown={e => {
                             downX = e.clientX;
                             downY = e.clientY;
@@ -1089,7 +1090,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     };
 
     @computed get renderBorder() {
-        const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.None);
+        const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.WhenAdded);
         const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; label: string } };
         return (
             <div className={`treeView-border${this.props.treeView.outlineMode ? TreeViewType.outline : ''}`} style={{ borderColor: sortings[sorting]?.color }}>
@@ -1131,7 +1132,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
     public static sortDocs(childDocs: Doc[], criterion: string | undefined) {
         const docs = childDocs.slice();
-        if (criterion !== TreeSort.None) {
+        if (criterion !== TreeSort.WhenAdded) {
             const sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
                 const reN = /[0-9]*$/;
                 const aA = a.replace(reN, '') ? a.replace(reN, '') : +a; // get rid of trailing numbers
@@ -1146,8 +1147,8 @@ export class TreeView extends React.Component<TreeViewProps> {
                 }
             };
             docs.sort(function (d1, d2): 0 | 1 | -1 {
-                const a = criterion === TreeSort.Up ? d2 : d1;
-                const b = criterion === TreeSort.Up ? d1 : d2;
+                const a = criterion === TreeSort.AlphaUp ? d2 : d1;
+                const b = criterion === TreeSort.AlphaUp ? d1 : d2;
                 const first = a[criterion === TreeSort.Zindex ? 'zIndex' : 'title'];
                 const second = b[criterion === TreeSort.Zindex ? 'zIndex' : 'title'];
                 if (typeof first === 'number' && typeof second === 'number') return first - second > 0 ? 1 : -1;
@@ -1198,7 +1199,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
         }
 
-        const docs = TreeView.sortDocs(childDocs, StrCast(treeView_Parent.treeView_SortCriterion, TreeSort.None));
+        const docs = TreeView.sortDocs(childDocs, StrCast(treeView_Parent.treeView_SortCriterion, TreeSort.WhenAdded));
         const rowWidth = () => panelWidth() - treeBulletWidth() * (treeView.props.NativeDimScaling?.() || 1);
         const treeView_Refs = new Map<Doc, TreeView | undefined>();
         return docs
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
index f87a06033..cb0d5e03f 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
@@ -9,6 +9,12 @@
         flex-direction: column;
         width: 100%;
         align-items: center;
+        position: relative;
+        > .iconButton-container {
+            top: 0;
+            left: 0;
+            position: absolute;
+        }
 
         .contentFittingDocumentView {
             width: unset;
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 10532b9d9..80da4e1a2 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,3 +1,5 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Button } from 'browndash-components';
 import { action, computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -6,7 +8,7 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types
 import { returnFalse } from '../../../../Utils';
 import { DragManager, dropActionType } from '../../../util/DragManager';
 import { Transform } from '../../../util/Transform';
-import { undoBatch } from '../../../util/UndoManager';
+import { undoable, undoBatch } from '../../../util/UndoManager';
 import { DocumentView } from '../../nodes/DocumentView';
 import { CollectionSubView } from '../CollectionSubView';
 import './CollectionMulticolumnView.scss';
@@ -301,6 +303,9 @@ export class CollectionMulticolumnView extends CollectionSubView() {
             collector.push(
                 <div className="document-wrapper" key={'wrapper' + i} style={{ width: width() }}>
                     {this.getDisplayDoc(layout, dxf, docwidth, docheight, shouldNotScale)}
+                    <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={undoable(e => {
+                        this.props.removeDocument?.(layout);
+                    }, "close doc")} color={StrCast(Doc.UserDoc().userColor)} />
                     <WidthLabel layout={layout} collectionDoc={Document} />
                 </div>,
                 <ResizeBar
-- 
cgit v1.2.3-70-g09d2

