From 7c83bc30b3a6ed6061ef68bcef6a0e8941668b3c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 26 Aug 2021 19:17:53 -0400
Subject: fixed resizing bug for web and pdf documents when doing autoheight
 gesture, and after opening the sidebar and then resizing

---
 src/client/views/collections/CollectionStackingView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b9bc83d49..4fedda1bd 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -144,7 +144,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             () => this.layoutDoc._columnHeaders = new List()
         );
         this._autoHeightDisposer = reaction(() => this.layoutDoc._autoHeight,
-            () => this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
+            autoHeight => autoHeight && this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
                 this.headerMargin + (this.isStackingView ?
                     Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))) :
                     this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0)))));
-- 
cgit v1.2.3-70-g09d2


From 12d8267533d9b646247914e965b3cf7c32019e4b Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Thu, 2 Sep 2021 04:45:01 -0400
Subject: Many updates

- Fixed image uploads so it clones rather than makes an alias
- Updated context menu
- Removed tools panel from novice mode in favour of ":" menu
- Added explainers to menus in novice mode
- Re-added the trails button
- Changed UI for text, PDF & websites so that it is more consistent
---
 src/client/documents/Documents.ts                  |  52 +++++----
 src/client/util/CurrentUserUtils.ts                |  93 ++++++++--------
 src/client/views/ContextMenu.scss                  |   2 +-
 src/client/views/ContextMenuItem.tsx               |   4 +-
 src/client/views/MainViewModal.scss                |   3 +-
 src/client/views/PropertiesButtons.scss            |  41 +++++--
 src/client/views/PropertiesButtons.tsx             |  53 +++++----
 src/client/views/SidebarAnnos.tsx                  |   3 +-
 src/client/views/StyleProvider.tsx                 |   4 +-
 .../views/collections/CollectionSchemaView.tsx     |   2 +-
 .../views/collections/CollectionStackingView.scss  |  24 +++++
 .../views/collections/CollectionStackingView.tsx   | 119 +++++++++++++++------
 .../views/collections/CollectionTreeView.tsx       |  95 ++++++++++++----
 src/client/views/collections/TabDocView.tsx        |   3 +-
 src/client/views/collections/TreeView.tsx          |   5 +-
 .../collectionLinearView/CollectionLinearView.scss |   6 +-
 .../collectionSchema/CollectionSchemaHeaders.tsx   |   2 +-
 .../collectionSchema/CollectionSchemaView.tsx      |   2 +-
 src/client/views/nodes/AudioBox.tsx                |   4 +-
 src/client/views/nodes/DocumentView.tsx            |   4 +-
 src/client/views/nodes/PDFBox.scss                 |  16 ++-
 src/client/views/nodes/PDFBox.tsx                  |  13 ++-
 src/client/views/nodes/WebBox.scss                 |   9 +-
 src/client/views/nodes/WebBox.tsx                  |  13 ++-
 src/client/views/nodes/button/FontIconBox.scss     |  29 ++++-
 src/client/views/nodes/button/FontIconBox.tsx      |  15 +--
 .../nodes/formattedText/FormattedTextBox.scss      |  21 +++-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  16 ++-
 src/client/views/search/SearchBox.tsx              |   2 +-
 src/client/views/topbar/TopBar.scss                |   4 +-
 src/client/views/topbar/TopBar.tsx                 |   3 +-
 31 files changed, 460 insertions(+), 202 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index c4a713dc6..bd247bd01 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -59,6 +59,7 @@ import { WebBox } from "../views/nodes/WebBox";
 import { SearchBox } from "../views/search/SearchBox";
 import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
 import { DocumentType } from "./DocumentTypes";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
 const path = require('path');
 
 const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", ""));
@@ -272,7 +273,12 @@ export class DocumentOptions {
     treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view
     treeViewHideHeader?: boolean; // whether to hide the header for a document in a tree view
     treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items.
-    treeViewShowClearButton?: boolean; // whether a clear button should be displayed 
+
+    // Action Button
+    buttonMenu?: boolean; // whether a action button should be displayed 
+    buttonMenuDoc?: Doc;
+    explainer?:string;
+
     treeViewOpenIsTransient?: boolean; // ignores the treeViewOpen Doc flag, allowing a treeViewItem's expand/collapse state to be independent of other views of the same document in the same or any other tree view
     _treeViewOpen?: boolean; // whether this document is expanded in a tree view  (note: need _ and regular versions since this can be specified for both proto and layout docs)
     treeViewOpen?: boolean; // whether this document is expanded in a tree view
@@ -1165,7 +1171,7 @@ export namespace DocUtils {
 
     export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false): void {
         !simpleMenu && ContextMenu.Instance.addItem({
-            description: "Add Note ...",
+            description: "Quick Notes",
             subitems: DocListCast((Doc.UserDoc()["template-notes"] as Doc).data).map((note, i) => ({
                 description: ":" + StrCast(note.title),
                 event: undoBatch((args: { x: number, y: number }) => {
@@ -1178,12 +1184,12 @@ export namespace DocUtils {
                     textDoc[textDoc.layoutKey] = note;
                     docTextAdder(textDoc);
                 }),
-                icon: "eye"
+                icon: StrCast(note.icon) as IconProp
             })) as ContextMenuProps[],
-            icon: "eye"
+            icon: "sticky-note"
         });
-        ContextMenu.Instance.addItem({
-            description: ":=math", event: () => {
+        const math:ContextMenuProps = ({
+            description: ":Math", event: () => {
                 const created = Docs.Create.EquationDocument();
                 if (created) {
                     created.author = Doc.CurrentUserEmail;
@@ -1194,25 +1200,27 @@ export namespace DocUtils {
                     EquationBox.SelectOnLoad = created[Id];
                     docAdder?.(created);
                 }
-            }, icon: "compress-arrows-alt"
+            }, icon: "calculator"
         });
+        const documentList:ContextMenuProps[] = DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({
+            description: ":" + StrCast(dragDoc.title),
+            event: undoBatch((args: { x: number, y: number }) => {
+                const newDoc = Doc.copyDragFactory(dragDoc);
+                if (newDoc) {
+                    newDoc.author = Doc.CurrentUserEmail;
+                    newDoc.x = x;
+                    newDoc.y = y;
+                    if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
+                    docAdder?.(newDoc);
+                }
+            }),
+            icon: Doc.toIcon(dragDoc),
+        })) as ContextMenuProps[]; 
+        documentList.push(math)
         ContextMenu.Instance.addItem({
             description: "Create document",
-            subitems: DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({
-                description: ":" + StrCast(dragDoc.title),
-                event: undoBatch((args: { x: number, y: number }) => {
-                    const newDoc = Doc.copyDragFactory(dragDoc);
-                    if (newDoc) {
-                        newDoc.author = Doc.CurrentUserEmail;
-                        newDoc.x = x;
-                        newDoc.y = y;
-                        if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
-                        docAdder?.(newDoc);
-                    }
-                }),
-                icon: Doc.toIcon(dragDoc),
-            })) as ContextMenuProps[],
-            icon: "eye"
+            subitems: documentList,
+            icon: "file"
         });
     }// applies a custom template to a document.  the template is identified by it's short name (e.g, slideView not layout_slideView)
     export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index f12ac02f3..f6ec74482 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -84,7 +84,7 @@ export class CurrentUserUtils {
                 title: "NEW MOBILE BUTTON",
                 onClick: undefined,
             },
-                [this.ficon({
+                [this.createToolButton({
                     ignoreClick: true,
                     icon: "mobile",
                     btnType: ButtonType.ToolButton,
@@ -92,7 +92,7 @@ export class CurrentUserUtils {
                 }),
                 this.mobileTextContainer({},
                     [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
-            doc["template-mobile-button"] = CurrentUserUtils.ficon({
+            doc["template-mobile-button"] = CurrentUserUtils.createToolButton({
                 onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
                 dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile", btnType: ButtonType.ToolButton,
             });
@@ -107,7 +107,7 @@ export class CurrentUserUtils {
                 { _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
             );
             slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
-            doc["template-button-slides"] = CurrentUserUtils.ficon({
+            doc["template-button-slides"] = CurrentUserUtils.createToolButton({
                 onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
                 dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card",
                 btnType: ButtonType.ToolButton
@@ -154,7 +154,7 @@ export class CurrentUserUtils {
             };
             linkTemplate.header = new RichTextField(JSON.stringify(rtf2), "");
 
-            doc["template-button-link"] = CurrentUserUtils.ficon({
+            doc["template-button-link"] = CurrentUserUtils.createToolButton({
                 onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
                 dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true,
                 btnType: ButtonType.ToolButton
@@ -186,7 +186,7 @@ export class CurrentUserUtils {
             const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, system: true });
             box.isTemplateDoc = makeTemplate(box, true, "switch");
 
-            doc["template-button-switch"] = CurrentUserUtils.ficon({
+            doc["template-button-switch"] = CurrentUserUtils.createToolButton({
                 onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
                 dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true,
                 btnType: ButtonType.ToolButton
@@ -236,7 +236,7 @@ export class CurrentUserUtils {
             short.title = "A Short Description";
             long.title = "Long Description";
 
-            doc["template-button-detail"] = CurrentUserUtils.ficon({
+            doc["template-button-detail"] = CurrentUserUtils.createToolButton({
                 onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
                 dragFactory: new PrefetchProxy(detailView) as any as Doc,
                 title: "detailView",
@@ -275,7 +275,7 @@ export class CurrentUserUtils {
     static setupNoteTemplates(doc: Doc) {
         if (doc["template-note-Note"] === undefined) {
             const noteView = Docs.Create.TextDocument("", {
-                title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true,
+                title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true, icon: "sticky-note",
                 _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
             });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Note");
@@ -283,7 +283,7 @@ export class CurrentUserUtils {
         }
         if (doc["template-note-Idea"] === undefined) {
             const noteView = Docs.Create.TextDocument("", {
-                title: "text", backgroundColor: "pink", system: true,
+                title: "text", backgroundColor: "pink", system: true, icon: "lightbulb",
                 _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
             });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea");
@@ -291,7 +291,7 @@ export class CurrentUserUtils {
         }
         if (doc["template-note-Topic"] === undefined) {
             const noteView = Docs.Create.TextDocument("", {
-                title: "text", backgroundColor: "lightblue", system: true,
+                title: "text", backgroundColor: "lightblue", system: true, icon: "book-open",
                 _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
             });
             noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic");
@@ -467,7 +467,7 @@ export class CurrentUserUtils {
             ((doc.emptyHeader as Doc).proto as Doc)["dragFactory-count"] = 0;
         }
         if (doc.emptyComparison === undefined) {
-            doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "compare", _width: 300, _height: 300, system: true, cloneFieldFilter: new List<string>(["system"]) });
+            doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "comparison box", _width: 300, _height: 300, system: true, cloneFieldFilter: new List<string>(["system"]) });
         }
         if (doc.emptyScript === undefined) {
             doc.emptyScript = Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250, title: "script", system: true, cloneFieldFilter: new List<string>(["system"]) });
@@ -512,7 +512,7 @@ export class CurrentUserUtils {
             { toolTip: "Tap to create a progressive slide", title: "Slide", icon: "file", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySlide as Doc },
             { toolTip: "Tap to create a cat image in a new pane, drag for a cat image", title: "Image", icon: "cat", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyImage as Doc },
             { toolTip: "Tap to create a comparison box in a new pane, drag for a comparison box", title: "Compare", icon: "columns", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyComparison as Doc, noviceMode: true },
-            { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc, noviceMode: true },
+            { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc },
             { toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc },
             { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true },
             { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc },
@@ -561,7 +561,7 @@ export class CurrentUserUtils {
         if (dragCreatorSet === undefined) {
             doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, {
                 title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true,
-                _forceActive: true, _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true,
+                _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 40, ignoreClick: true, _lockedPosition: true,
                 dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
             }));
         } else {
@@ -574,29 +574,31 @@ export class CurrentUserUtils {
         return [
             { title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
             { title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' },
-            { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' },
-            { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' },
-            { title: "Import", target: Cast(doc.myImportDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
+            { title: "File Manager", target: Cast(doc.myFilesystem, Doc, null), icon: "folder-open", click: 'selectMainMenu(self)' },
+            { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
+            { title: "Uploads", target: Cast(doc.myUploadDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
             { title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' },
             { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc },
             { title: "Trails", target: Cast(doc.myTrails, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
-            { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' },
+            { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
         ];
     }
 
     static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
         if (doc.menuStack === undefined) {
             await this.setupSharingSidebar(doc, sharingDocumentId, linkDatabaseId);  // sets up the right sidebar collection for mobile upload documents and sharing
-            const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments }) =>
+            const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments, hidden }) =>
                 Docs.Create.FontIconDocument({
                     icon,
                     btnType: ButtonType.MenuButton,
                     _stayInCollection: true,
                     _hideContextMenu: true,
+                    _chromeHidden: true,
                     system: true,
                     dontUndo: true,
                     title,
                     target,
+                    hidden: hidden ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined,
                     _dropAction: "alias",
                     _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
                     _width: 60,
@@ -611,8 +613,6 @@ export class CurrentUserUtils {
                     this.searchBtn = menuBtn;
                 }
             });
-            // hack -- last button is assumed to be the userDoc
-            menuBtns[menuBtns.length - 1].hidden = ComputedField.MakeFunction("IsNoviceMode()");
 
             menuBtns.forEach(menuBtn => {
                 if (menuBtn.title === "Search") {
@@ -684,7 +684,7 @@ export class CurrentUserUtils {
                 onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
                 backgroundColor: data.backgroundColor, system: true
             },
-                [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
+                [this.createToolButton({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
         );
     }
 
@@ -820,6 +820,7 @@ export class CurrentUserUtils {
             const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
             (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, shareDashboard!, removeDashboard!]);
             (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]);
+            (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "share", "times"]);
             // (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
             // (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
         }
@@ -860,18 +861,21 @@ export class CurrentUserUtils {
     }
 
     static setupRecentlyClosedDocs(doc: Doc) {
-        // setup Recently Closed library item
         if (doc.myRecentlyClosedDocs === undefined) {
-            const clearDocs = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript(`getProto(self).data = new List([])`), toolTip: "Empty", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.TextButton, _width: 200, buttonText: "Empty Recently Closed", icon: "trash", system: true });
-            doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([clearDocs], {
-                title: "My Recently Closed", _showTitle: "title", treeViewShowClearButton: true, childHideLinkButton: true,
+            const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`);
+            const clearDocsButton:Doc = Docs.Create.FontIconDocument({ onClick: clearAll, _forceActive: true, toolTip: "Empty recently closed", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "Empty", icon: "trash", system: true });
+            doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], {
+                title: "My Recently Closed", _showTitle: "title", buttonMenu: true, buttonMenuDoc: clearDocsButton, childHideLinkButton: true,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
-                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
+                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
+                explainer: "Documents that you close will appear here so you can easily access them again. You can choose to clear this menu in which case you might lose these documents."
+
             }));
-            const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`);
             (doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List<ScriptField>([clearAll!]);
-            (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Clear All"]);
+            (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Empty recently closed"]);
+            (doc.myRecentlyClosedDocs as any as Doc).contextMenuIcons = new List<string>(["trash"]);
+
         }
     }
 
@@ -916,7 +920,7 @@ export class CurrentUserUtils {
     static async setupSidebarButtons(doc: Doc) {
         CurrentUserUtils.setupSidebarContainer(doc);
         await CurrentUserUtils.setupToolsBtnPanel(doc);
-        CurrentUserUtils.setupImportSidebar(doc);
+        CurrentUserUtils.setupUploadSidebar(doc);
         CurrentUserUtils.setupDashboards(doc);
         CurrentUserUtils.setupPresentations(doc);
         CurrentUserUtils.setupFilesystem(doc);
@@ -930,17 +934,17 @@ export class CurrentUserUtils {
         _lockedPosition: true, system: true, flexDirection: "row"
     })) as any as Doc
 
-    static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
-        ...opts, _dropAction: "alias", _removeDropProperties: new List<string>(["_dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
+    static createToolButton = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
+        ...opts, btnType: ButtonType.ToolButton, _forceActive: true, _dropAction: "alias", _removeDropProperties: new List<string>(["_dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
     })) as any as Doc
 
     /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
     static setupDockedButtons(doc: Doc) {
         if (doc["dockedBtn-undo"] === undefined) {
-            doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true });
+            doc["dockedBtn-undo"] = CurrentUserUtils.createToolButton({ onClick: ScriptField.MakeScript("undo()"), _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true });
         }
         if (doc["dockedBtn-redo"] === undefined) {
-            doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true });
+            doc["dockedBtn-redo"] = CurrentUserUtils.createToolButton({ onClick: ScriptField.MakeScript("redo()"), _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true });
         }
         if (doc.dockedBtns === undefined) {
             doc.dockedBtns = CurrentUserUtils.linearButtonList({ title: "docked buttons", _height: 40, flexGap: 0, linearViewFloating: true, linearViewIsExpanded: true, linearViewExpandable: true, ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]);
@@ -1039,7 +1043,7 @@ export class CurrentUserUtils {
             // { title: "Alias", btnType: ButtonType.ClickButton, icon: "copy", hidden: 'selectedDocumentType()' }, // Only when a document is selected 
             { title: "Text", type: "textTools", subMenu: true, expanded: 'selectedDocumentType("rtf")' }, // Always available
             { title: "Ink", type: "inkTools", subMenu: true, expanded: 'selectedDocumentType("ink")' }, // Always available
-            // { title: "Web", type: "webTools", subMenu: true, hidden: 'selectedDocumentType("web")' }, // Only when Web is selected
+            { title: "Web", type: "webTools", subMenu: true, hidden: 'selectedDocumentType("web")' }, // Only when Web is selected
             { title: "Schema", type: "schemaTools", subMenu: true, hidden: 'selectedDocumentType(undefined, "schema")' } // Only when Schema is selected
         ];
     }
@@ -1172,13 +1176,15 @@ export class CurrentUserUtils {
             }
             doc.myLinkDatabase = new PrefetchProxy(linkDocs);
         }
+        // TODO:glr NOTE: treeViewHideTitle & _showTitle may be confusing, treeViewHideTitle is for the editable title (just for tree view), _showTitle is to show the Document title for any document
         if (doc.mySharedDocs === undefined) {
             let sharedDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(sharingDocumentId + "outer");
             if (!sharedDocs) {
                 sharedDocs = Docs.Create.TreeDocument([], {
                     title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
-                    _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
+                    _showTitle: "title", treeViewHideTitle: true, ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
                     _chromeHidden: true, boxShadow: "0 0",
+                    explainer: "All of the documents that you receive will appear here. They must be shared by other users. If you receive a Dashboard you can add it to your Dashboards by right clicking and clicking 'Add to Dashboards'"
                 }, sharingDocumentId + "outer", sharingDocumentId);
                 (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Augment;
             }
@@ -1189,18 +1195,21 @@ export class CurrentUserUtils {
                 sharedDocs.childContextMenuFilters = new List<ScriptField>([dashboardFilter!,]);
                 sharedDocs.childContextMenuScripts = new List<ScriptField>([addToDashboards!,]);
                 sharedDocs.childContextMenuLabels = new List<string>(["Add to Dashboards",]);
+                sharedDocs.childContextMenuIcons = new List<string>(["user-plus",]);
+
             }
             doc.mySharedDocs = new PrefetchProxy(sharedDocs);
         }
     }
 
     // Import sidebar is where shared documents are contained
-    static setupImportSidebar(doc: Doc) {
-        if (doc.myImportDocs === undefined) {
-            const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Upload from computer", _width: 100, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.TextButton, buttonText: "Upload from computer", icon: "upload", system: true });
-            doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([newUpload], {
-                title: "My Uploads", _forceActive: true, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
-                childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
+    static setupUploadSidebar(doc: Doc) {
+        if (doc.myUploadDocs === undefined) {
+            const newUploadButton:Doc = Docs.Create.FontIconDocument({ onClick: ScriptField.MakeScript("importDocument()"), _forceActive: true, toolTip: "Upload from computer", _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.ClickButton, buttonText: "Upload", icon: "upload", system: true });
+            doc.myUploadDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
+                title: "My Uploads", _forceActive: true, buttonMenu: true, buttonMenuDoc: newUploadButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
+                childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
+                explainer: "All of the documents that are imported into Dash will go here and stay here unless they are explicitly removed."
             }));
         }
     }
@@ -1303,7 +1312,7 @@ export class CurrentUserUtils {
         doc.filterDocCount = 0;
         this.setupDefaultIconTemplates(doc);  // creates a set of icon templates triggered by the document deoration icon
         this.setupDocTemplates(doc); // sets up the template menu of templates
-        this.setupImportSidebar(doc); // sets up the import sidebar
+        this.setupUploadSidebar(doc); // sets up the import sidebar
         this.setupSearchSidebar(doc); // sets up the search sidebar
         this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
         this.setupOverlays(doc);  // documents in overlay layer
@@ -1430,7 +1439,7 @@ export class CurrentUserUtils {
                     }
                 }
             } else if (input.files && input.files.length !== 0) {
-                const importDocs = Cast(Doc.UserDoc().myImportDocs, Doc, null);
+                const importDocs = Cast(Doc.UserDoc().myUploadDocs, Doc, null);
                 const disposer = OverlayView.ShowSpinner();
                 DocListCastAsync(importDocs.data).then(async list => {
                     const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {});
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 41a6dc569..47ae0424b 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -130,7 +130,7 @@
 }
 
 .contextMenu-inlineMenu {
-    border-top: solid 1px;
+    // border-top: solid 1px; //TODO:glr clean
 }
 
 .contextMenu-item:hover {
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 168fcb888..c3921d846 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -116,12 +116,12 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
                     style={{ alignItems: where, borderTop: this.props.addDivider ? "solid 1px" : undefined }}
                     onMouseLeave={this.onPointerLeave} onMouseEnter={this.onPointerEnter}>
                     {this.props.icon ? (
-                        <span className="icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: "center" }}>
+                        <span className="icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: "center", alignSelf: "center" }}>
                             <FontAwesomeIcon icon={this.props.icon} size="sm" />
                         </span>
                     ) : null}
                     <div className="contextMenu-description" onMouseEnter={this.onPointerEnter}
-                        style={{ alignItems: "center" }} >
+                        style={{ alignItems: "center", alignSelf: "center" }} >
                         {this.props.description}
                         <FontAwesomeIcon icon={"angle-right"} size="lg" style={{ position: "absolute", right: "10px" }} />
                     </div>
diff --git a/src/client/views/MainViewModal.scss b/src/client/views/MainViewModal.scss
index 03cb5cc84..0648e31c5 100644
--- a/src/client/views/MainViewModal.scss
+++ b/src/client/views/MainViewModal.scss
@@ -6,6 +6,7 @@
     height: 100%;
 
     .dialogue-box {
+        padding: 10px;
         position: absolute;
         z-index: 1000;
         text-align: center;
@@ -13,7 +14,7 @@
         align-self: center;
         align-content: center;
         background: white;
-        border-radius: 10px;
+        // border-radius: 10px;
         box-shadow: #00000044 5px 5px 10px;
         transform: translate(-50%, -50%);
         top: 50%;
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 484522bc7..77686a710 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -67,10 +67,12 @@ $linkGap : 3px;
 }
 
 .onClickFlyout-editScript {
+    cursor: pointer;
     text-align: center;
-    border: 0.5px solid grey;
+    margin-top: 5px;
+    border: 0.5px solid $medium-gray;
     background-color: rgb(230, 230, 230);
-    border-radius: 9px;
+    border-radius: 5px;
     padding: 4px;
 }
 
@@ -84,9 +86,32 @@ $linkGap : 3px;
     margin-bottom: 8px;
 }
 
+.propertiesButton-dropdownList {
+    width: 100%;
+    height: fit-content;
+    top: 100%;
+    z-index: 21;
+
+    .list-item {
+        cursor: pointer;
+        color: $black;
+        width: 100%;
+        height: 25px;
+        font-weight: 400;
+        display: flex;
+        justify-content: left;
+        align-items: center;
+        padding-left: 5px;
+    }
+
+    .list-item:hover {
+        background-color: lightgrey;
+    }
+}
+
 .propertiesButtons-title {
-    background: #121721;
-    color: white;
+    background: $dark-gray;
+    color: $white;
     font-size: 6px;
     width: 37px;
     padding: 3px;
@@ -111,17 +136,11 @@ $linkGap : 3px;
     margin-left: 4px;
 
     &:hover {
-        background: $medium-gray;
-        transform: scale(1.05);
+        filter:brightness(0.85);
         cursor: pointer;
     }
 }
 
-.propertiesButtons-linker:hover {
-    cursor: pointer;
-    transform: scale(1.05);
-}
-
 
 @-moz-keyframes spin {
     100% {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index dcab9bc1e..4fde1124f 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -15,6 +15,7 @@ import { InkingStroke } from './InkingStroke';
 import { DocumentView } from './nodes/DocumentView';
 import './PropertiesButtons.scss';
 import React = require("react");
+import { Colors } from "./global/globalEnums";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -128,11 +129,11 @@ export class PropertiesButtons extends React.Component<{}, {}> {
 
     @undoBatch
     @action
-    handleOptionChange = (e: any) => {
-        this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value);
+    handleOptionChange = (onClick: string) => {
+        this.selectedDoc && (this.selectedDoc.onClickBehavior = onClick);
         SelectionManager.Views().filter(dv => dv.docView).map(dv => dv.docView!).forEach(docView => {
             docView.noOnClick();
-            switch (e.target.value) {
+            switch (onClick) {
                 case "enterPortal": docView.makeIntoPortal(); break;
                 case "toggleDetail": docView.setToggleDetail(); break;
                 case "linkInPlace": docView.toggleFollowLink("inPlace", true, false); break;
@@ -149,20 +150,34 @@ export class PropertiesButtons extends React.Component<{}, {}> {
 
     @computed
     get onClickFlyout() {
-        const makeLabel = (value: string, label: string) => <div className="radio">
-            <label>
-                <input type="radio" value={value} checked={(this.selectedDoc?.onClickBehavior ?? "nothing") === value} onChange={this.handleOptionChange} />
-                {label}
-            </label>
-        </div>;
+        const buttonList = [
+            ["nothing", "Select Document"],
+            ["enterPortal", "Enter Portal"],
+            ["toggleDetail", "Toggle Detail"],
+            ["linkInPlace", "Follow Link"],
+            ["linkOnRight", "Open Link on Right"]
+        ]
+        const currentSelection = this.selectedDoc.onClickBehavior;
+        // Get items to place into the list
+
+        const list = buttonList.map((value) => {
+            const click = () => {
+                this.handleOptionChange(value[0]);
+            };
+            return <div className="list-item" key={`${value}`}
+                style={{
+                    backgroundColor: value[0] === currentSelection ? Colors.LIGHT_BLUE : undefined
+                }}
+                onClick={click}>
+                {value[1]}
+            </div>;
+        });
         return <div>
-            <form>
-                {makeLabel("nothing", "Select Document")}
-                {makeLabel("enterPortal", "Enter Portal")}
-                {makeLabel("toggleDetail", "Toggle Detail")}
-                {makeLabel("linkInPlace", "Follow Link")}
-                {makeLabel("linkOnRight", "Open Link on Right")}
-            </form>
+            <div>
+                <div className="propertiesButton-dropdownList">
+                    {list}
+                </div>
+            </div>
             {Doc.UserDoc().noviceMode ? (null) : <div onPointerDown={this.editOnClickScript} className="onClickFlyout-editScript"> Edit onClick Script</div>}
         </div>;
     }
@@ -190,7 +205,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform;
         const isTree = this.selectedDoc?._viewType === CollectionViewType.Tree;
         const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => <div className="propertiesButtons-button" style={style}> {ele} </div>;
-
+        const isNovice = Doc.UserDoc().noviceMode;
         return !this.selectedDoc ? (null) :
             <div className="propertiesButtons">
                 {toggle(this.titleButton)}
@@ -198,7 +213,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 {toggle(this.lockButton)}
                 {toggle(this.dictationButton)}
                 {toggle(this.onClickButton)}
-                {toggle(this.fitWidthButton)}
+                {toggle(this.fitWidthButton, { display: isNovice ? "none" : "" })}
                 {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })}
                 {toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })}
                 {toggle(this.maskButton, { display: !isInk ? "none" : "" })}
@@ -207,7 +222,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 {toggle(this.snapButton, { display: isCollection ? "" : "none" })}
                 {toggle(this.clustersButton, { display: !isFreeForm ? "none" : "" })}
                 {toggle(this.panButton, { display: !isFreeForm ? "none" : "" })}
-                {toggle(this.perspectiveButton, { display: !isCollection ? "none" : "" })}
+                {toggle(this.perspectiveButton, { display: !isCollection || isNovice ? "none" : "" })}
             </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 0e3663f65..01b79ffd2 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -106,9 +106,10 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
                 {user}
             </div>;
         };
+        // TODO: Calculation of the topbar is hardcoded and different for text nodes - it should all be the same and all be part of SidebarAnnos
         return !this.props.showSidebar ? (null) :
             <div style={{
-                position: "absolute", pointerEvents: this.props.isContentActive() ? "all" : undefined, top: 0, right: 0,
+                position: "absolute", pointerEvents: this.props.isContentActive() ? "all" : undefined, top: this.props.rootDoc.type !== DocumentType.RTF && StrCast(this.props.rootDoc._showTitle) === "title" ? 15 : 0, right: 0,
                 background: this.props.styleProvider?.(this.props.rootDoc, this.props, StyleProp.WidgetColor),
                 width: `${this.panelWidth()}px`,
                 height: "100%"
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index fa35081bc..e528e84e3 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -89,7 +89,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
     switch (property.split(":")[0]) {
         case StyleProp.TreeViewIcon: return Doc.toIcon(doc, isOpen);
         case StyleProp.DocContents: return undefined;
-        case StyleProp.WidgetColor: return isAnnotated ? "lightBlue" : darkScheme() ? "lightgrey" : "dimgrey";
+        case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : darkScheme() ? "lightgrey" : "dimgrey";
         case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null));
         case StyleProp.HideLinkButton: return props?.hideLinkButton || (!selected && (doc?.isLinkButton || doc?.hideLinkButton));
         case StyleProp.FontSize: return StrCast(doc?.[fieldKey + "fontSize"]);
@@ -108,7 +108,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.TitleHeight: return 15;
         case StyleProp.BorderPath: return comicStyle() && props?.renderDepth ? { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, .08), width: 3 } : { path: undefined, width: 0 };
         case StyleProp.JitterRotation: return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0;
-        case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) ||
+        case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
             doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
         case StyleProp.BackgroundColor: {
             if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 6bdeaf722..6a22acae8 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -338,7 +338,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             {this.renderColors(this._col)}
             <div className="collectionSchema-headerMenu-group">
                 <button onClick={() => { this.deleteColumn(this._col.heading); }}
-                >Delete Column</button>
+                >Hide Column</button>
             </div>
         </div>;
     }
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 4b123c8b6..2f002736d 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -14,6 +14,30 @@
     width: 100%;
 }
 
+// TODO:glr Turn this into a seperate class
+.documentButtonMenu {
+    position: relative;
+    height: fit-content;
+    border-bottom: $standard-border;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+    align-content: center;
+    padding: 5px 0 5px 0;
+
+    .documentExplanation {
+        width: 90%;
+        margin: 5px;
+        font-size: 11px;
+        background-color: $light-blue;
+        color: $medium-blue;
+        padding: 10px;
+        border-radius: 10px;
+        border: solid 2px $medium-blue;
+    }
+}
+
 .collectionStackingView,
 .collectionMasonryView {
     height: 100%;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4fedda1bd..3c9084f64 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { CursorProperty } from "csstype";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../fields/Doc";
 import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
 import { Id } from "../../../fields/FieldSymbols";
 import { List } from "../../../fields/List";
@@ -11,7 +11,7 @@ import { listSpec, makeInterface } from "../../../fields/Schema";
 import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
 import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils";
+import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils, returnTrue, returnEmptyDoclist, returnEmptyFilter } from "../../../Utils";
 import { DocUtils, Docs } from "../../documents/Documents";
 import { DragManager, dropActionType } from "../../util/DragManager";
 import { SnappingManager } from "../../util/SnappingManager";
@@ -23,12 +23,14 @@ import { EditableView } from "../EditableView";
 import { LightboxView } from "../LightboxView";
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
 import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView";
-import { StyleProp } from "../StyleProvider";
+import { StyleProp, DefaultStyleProvider } from "../StyleProvider";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 import "./CollectionStackingView.scss";
 import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn";
 import { CollectionSubView } from "./CollectionSubView";
 import { CollectionViewType } from "./CollectionView";
+import { FontIconBox } from "../nodes/button/FontIconBox";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 const _global = (window /* browser */ || global /* node */) as any;
 
 type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
@@ -514,6 +516,47 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         return sections.map((section, i) => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0));
     }
 
+    @computed get buttonMenu() {
+        const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
+        // TODO:glr Allow support for multiple buttons
+        if (menuDoc){
+            const width: number = NumCast(menuDoc._width, 30);
+            const height: number = NumCast(menuDoc._height, 30);
+            console.log(menuDoc.title, width, height);
+            return (<div className="buttonMenu-docBtn"
+                style = {{width: width, height: height}}>
+                <DocumentView
+                    Document={menuDoc}
+                    DataDoc={menuDoc}
+                    isContentActive={this.props.isContentActive}
+                    isDocumentActive={returnTrue}
+                    addDocument={this.props.addDocument}
+                    moveDocument={this.props.moveDocument}
+                    addDocTab={this.props.addDocTab}
+                    pinToPres={emptyFunction}
+                    rootSelected={this.props.isSelected}
+                    removeDocument={this.props.removeDocument}
+                    ScreenToLocalTransform={Transform.Identity}
+                    PanelWidth={() => 35}
+                    PanelHeight={() => 35}
+                    renderDepth={this.props.renderDepth}
+                    focus={emptyFunction}
+                    styleProvider={this.props.styleProvider}
+                    layerProvider={this.props.layerProvider}
+                    docViewPath={returnEmptyDoclist}
+                    whenChildContentsActiveChanged={emptyFunction}
+                    bringToFront={emptyFunction}
+                    docFilters={this.props.docFilters}
+                    docRangeFilters={this.props.docRangeFilters}
+                    searchFilterDocs={this.props.searchFilterDocs}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined} 
+                />
+            </div>
+            );
+        }
+    }
+
 
     @computed get nativeWidth() { return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc); }
     @computed get nativeHeight() { return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc); }
@@ -529,34 +572,50 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             SetValue: this.addGroup,
             contents: "+ ADD A GROUP"
         };
+        const buttonMenu = this.rootDoc.buttonMenu;
+        const noviceExplainer = this.rootDoc.explainer;
+        console.log(noviceExplainer);
         return (
-            <div className="collectionStackingMasonry-cont" >
-                <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
-                    ref={this.createRef}
-                    style={{
-                        overflowY: this.props.isContentActive() ? "auto" : "hidden",
-                        background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
-                        pointerEvents: this.backgroundEvents ? "all" : undefined
-                    }}
-                    onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
-                    onDrop={this.onExternalDrop.bind(this)}
-                    onContextMenu={this.onContextMenu}
-                    onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
-                    {this.renderedSections}
-                    {!this.showAddAGroup ? (null) :
-                        <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
-                            style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
-                            <EditableView {...editableViewProps} />
-                        </div>}
-                    {/* {this.chromeHidden || !this.props.isSelected() ? (null) :
-                        <Switch
-                            onChange={this.onToggle}
-                            onClick={this.onToggle}
-                            defaultChecked={true}
-                            checkedChildren="edit"
-                            unCheckedChildren="view"
-                        />} */}
-                </div> </div>
+            <>
+                {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
+                    {buttonMenu ? this.buttonMenu : null}
+                    {Doc.UserDoc().isNovice && noviceExplainer ? 
+                        <div className="documentExplanation">
+                            {noviceExplainer}
+                        </div>
+                        : null
+                    }
+                </div> : null}
+                <div className="collectionStackingMasonry-cont" >
+                    <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
+                        ref={this.createRef}
+                        style={{
+                            overflowY: this.props.isContentActive() ? "auto" : "hidden",
+                            background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
+                            pointerEvents: this.backgroundEvents ? "all" : undefined
+                        }}
+                        onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
+                        onDrop={this.onExternalDrop.bind(this)}
+                        onContextMenu={this.onContextMenu}
+                        onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
+                        {this.renderedSections}
+                        {!this.showAddAGroup ? (null) :
+                            <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
+                                style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
+                                <EditableView {...editableViewProps} />
+                            </div>}
+                        {/* {this.chromeHidden || !this.props.isSelected() ? (null) :
+                            <Switch
+                                onChange={this.onToggle}
+                                onClick={this.onToggle}
+                                defaultChecked={true}
+                                checkedChildren="edit"
+                                unCheckedChildren="view"
+                            />} */}
+                    </div> 
+                </div>
+            </>
+            
         );
     }
 }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 89d42439e..4d62a1af4 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -8,7 +8,7 @@ import { Document, listSpec } from '../../../fields/Schema';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
-import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, emptyFunction } from '../../../Utils';
 import { DocUtils } from '../../documents/Documents';
 import { CurrentUserUtils } from '../../util/CurrentUserUtils';
 import { DocumentManager } from '../../util/DocumentManager';
@@ -26,6 +26,7 @@ import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionTreeView.scss";
 import { TreeView } from "./TreeView";
 import React = require("react");
+import { Transform } from '../../util/Transform';
 const _global = (window /* browser */ || global /* node */) as any;
 
 export type collectionTreeViewProps = {
@@ -221,8 +222,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
     }
     childContextMenuItems = () => {
         const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
-        const filterScripts = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
-        return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: filterScripts[i], label }));
+        const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
+        const icons = StrListCast(this.doc.childContextMenuIcons);
+        return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
     }
     @computed get treeViewElements() {
         TraceMobx();
@@ -265,13 +267,48 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
         return hideTitle ? (null) : (this.outlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren);
     }
 
-    @computed get renderClearButton() {
-        return !this.doc.treeViewShowClearButton ? (null) : <div key="toolbar">
-            <button className="toolbar-button round-button" title="Empty" onClick={undoBatch(action(() => Doc.GetProto(this.doc)[this.props.fieldKey] = undefined))}>
-                <FontAwesomeIcon icon={"trash"} size="sm" />
-            </button>
-        </div >;
+    @computed get buttonMenu() {
+        const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
+        // To create a multibutton menu add a CollectionLinearView
+        if (menuDoc){
+            
+            const width: number = NumCast(menuDoc._width, 30);
+            const height: number = NumCast(menuDoc._height, 30);
+            console.log(menuDoc.title, width, height);
+            return (<div className="buttonMenu-docBtn"
+                style = {{width: width, height: height}}>
+                <DocumentView
+                    Document={menuDoc}
+                    DataDoc={menuDoc}
+                    isContentActive={this.props.isContentActive}
+                    isDocumentActive={returnTrue}
+                    addDocument={this.props.addDocument}
+                    moveDocument={this.props.moveDocument}
+                    addDocTab={this.props.addDocTab}
+                    pinToPres={emptyFunction}
+                    rootSelected={this.props.isSelected}
+                    removeDocument={this.props.removeDocument}
+                    ScreenToLocalTransform={Transform.Identity}
+                    PanelWidth={() => 35}
+                    PanelHeight={() => 35}
+                    renderDepth={this.props.renderDepth + 1}
+                    focus={emptyFunction}
+                    styleProvider={this.props.styleProvider}
+                    layerProvider={this.props.layerProvider}
+                    docViewPath={returnEmptyDoclist}
+                    whenChildContentsActiveChanged={emptyFunction}
+                    bringToFront={emptyFunction}
+                    docFilters={this.props.docFilters}
+                    docRangeFilters={this.props.docRangeFilters}
+                    searchFilterDocs={this.props.searchFilterDocs}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined} 
+                />
+            </div>);
+        }
     }
+
+    
     @computed get nativeWidth() { return Doc.NativeWidth(this.Document, undefined, true); }
     @computed get nativeHeight() { return Doc.NativeHeight(this.Document, undefined, true); }
 
@@ -295,22 +332,34 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
         TraceMobx();
         const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor);
         const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined;
+        const buttonMenu = this.rootDoc.buttonMenu;
+        const noviceExplainer = this.rootDoc.explainer;
 
         return !(this.doc instanceof Doc) || !this.treeChildren ? (null) :
-            <div className="collectionTreeView-container"
-                style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}}
-                onContextMenu={this.onContextMenu}>
-                <div className="collectionTreeView-dropTarget"
-                    style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
-                    onWheel={e => e.stopPropagation()}
-                    onDrop={this.onTreeDrop}
-                    ref={this.createTreeDropTarget}>
+               <>
                     {this.titleBar}
-                    {this.renderClearButton}
-                    <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} >
-                        {this.treeViewElements}
-                    </ul>
-                </div >
-            </div>;
+                    <div className="collectionTreeView-container"
+                        style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}}
+                        onContextMenu={this.onContextMenu}>
+                        {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
+                            {buttonMenu ? this.buttonMenu : null}
+                            {Doc.UserDoc().noviceMode && noviceExplainer ? 
+                                <div className="documentExplanation">
+                                    {noviceExplainer}
+                                </div>
+                                : null
+                            }
+                        </div> : null}
+                        <div className="collectionTreeView-dropTarget"
+                            style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
+                            onWheel={e => e.stopPropagation()}
+                            onDrop={this.onTreeDrop}
+                            ref={this.createTreeDropTarget}>
+                            <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} >
+                                {this.treeViewElements}
+                            </ul>
+                        </div >
+                    </div>
+               </>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 889db1ef6..34cb6ec55 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -387,9 +387,10 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     background={this.miniMapColor}
                     document={this._document}
                     tabView={this.tabView} />
-                <Tooltip style={{ display: this.disableMinimap() ? "none" : undefined }} key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}>
+                <Tooltip key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}>
                     <div className="miniMap-hidden"
                         style={{
+                            display: this.disableMinimap() || this._document._viewType !== "freeform" ? "none" : undefined,
                             color: this._document.hideMinimap ? Colors.BLACK : Colors.WHITE,
                             backgroundColor: this._document.hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
                             boxShadow: this._document.hideMinimap ? Shadows.STANDARD_SHADOW : undefined
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index b9487054b..8cf34ddcc 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -525,7 +525,8 @@ export class TreeView extends React.Component<TreeViewProps> {
     childContextMenuItems = () => {
         const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
         const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
-        return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], label }));
+        const icons = StrListCast(this.doc.childContextMenuIcons);
+        return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
     }
     onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
 
@@ -835,7 +836,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         dontRegisterView: boolean | undefined,
         observerHeight: (ref: any) => void,
         unobserveHeight: (ref: any) => void,
-        contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string }[])
+        contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string, icon: string }[])
     ) {
         const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField);
         if (viewSpecScript) {
diff --git a/src/client/views/collections/collectionLinearView/CollectionLinearView.scss b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
index f249eb1f5..8fe804466 100644
--- a/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
+++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
@@ -98,7 +98,11 @@
             transition: transform 0.2s;
             align-items: center;
             justify-content: center;
-            transition: 0.15s;
+            transition: 0.2s;
+
+            &:hover{
+                filter: brightness(0.85);
+            }
         }
 
         >input {
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
index b28c32e0e..a25f962df 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
@@ -191,7 +191,7 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
                         {this.renderSorting()}
                         {this.renderColors()}
                         <div className="collectionSchema-headerMenu-group">
-                            <button onClick={() => this.props.deleteColumn(this.props.columnField.heading)}>Delete Column</button>
+                            <button onClick={() => this.props.deleteColumn(this.props.columnField.heading)}>Hide Column</button>
                         </div>
                     </>
                 }
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index fed64b620..dfe99ffc8 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -338,7 +338,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             {this.renderColors(this._col)}
             <div className="collectionSchema-headerMenu-group">
                 <button onClick={() => { this.deleteColumn(this._col.heading); }}
-                >Delete Column</button>
+                >Hide Column</button>
             </div>
         </div>;
     }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index f5a7e61aa..8962d29f0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -638,12 +638,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
                                 </div>
                             </div>
                         ) : (
-                                <button
+                                <div
                                     className={`audiobox-record${interactive}`}
                                     style={{ backgroundColor: Colors.DARK_GRAY }}
                                 >
                                     RECORD
-                                </button>
+                                </div>
                             )}
                     </div>
                 ) : (
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7463e192f..98ae279db 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -635,7 +635,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     makeIntoPortal = async () => {
         const portalLink = this.allLinks.find(d => d.anchor1 === this.props.Document);
         if (!portalLink) {
-            const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + ".portal" });
+            const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + " [Portal]" });
             DocUtils.MakeLink({ doc: this.props.Document }, { doc: portal }, "portal to");
         }
         this.Document.followLinkLocation = "inPlace";
@@ -679,7 +679,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             const appearance = cm.findByDescription("UI Controls...");
             const appearanceItems: ContextMenuProps[] = appearance && "subitems" in appearance ? appearance.subitems : [];
             !Doc.UserDoc().noviceMode && templateDoc && appearanceItems.push({ description: "Open Template   ", event: () => this.props.addDocTab(templateDoc, "add:right"), icon: "eye" });
-            appearanceItems.push({
+            !Doc.UserDoc().noviceMode && appearanceItems.push({
                 description: "Add a Field", event: () => {
                     const alias = Doc.MakeAlias(this.rootDoc);
                     alias.layout = FormattedTextBox.LayoutString("newfield");
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 72dec6e4c..f44355929 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -1,3 +1,5 @@
+@import "../global/globalCssVariables.scss";
+
 .pdfBox,
 .pdfBox-interactive {
     display: inline-block;
@@ -18,12 +20,13 @@
         top: 0;
         left: 0;
 
+        // glr: This should really be the same component as text and PDFs
         .pdfBox-sidebarBtn {
-            background: #121721;
+            background: $black;
             height: 25px;
             width: 25px;
-            right: 0;
-            color: white;
+            right: 5px;
+            color: $white;
             display: flex;
             position: absolute;
             align-items: center;
@@ -31,6 +34,13 @@
             border-radius: 3px;
             pointer-events: all;
             z-index: 1; // so it appears on top of the document's title, if shown
+
+            box-shadow: $standard-box-shadow;
+            transition: 0.2s;
+
+            &:hover{
+                filter: brightness(0.85);
+            }
         }
 
         .pdfBox-pageNums {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5e07229c1..3a399bfdb 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -24,6 +24,7 @@ import { pageSchema } from "./ImageBox";
 import "./PDFBox.scss";
 import React = require("react");
 import { AnchorMenu } from '../pdf/AnchorMenu';
+import { Colors } from '../global/globalEnums';
 
 type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
 const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
@@ -208,11 +209,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                         onClick={action(() => this._pageControls = !this._pageControls)} />
                     {this._pageControls ? pageBtns : (null)}
                 </div>
-                <button className="pdfBox-sidebarBtn" title="Toggle Sidebar"
-                    style={{ display: !this.props.isContentActive() ? "none" : undefined }}
+                <div className="pdfBox-sidebarBtn" key="sidebar" title="Toggle Sidebar"
+                    style={{ 
+                        display: !this.props.isContentActive() ? "none" : undefined, 
+                        top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5,
+                        backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK
+                    }}
                     onPointerDown={this.sidebarBtnDown} >
-                    <FontAwesomeIcon icon={"chevron-left"} size="sm" />
-                </button>
+                        <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" />
+                </div>
             </div>;
     }
     sidebarWidth = () => !this.SidebarShown ? 0 :
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 19b69ff5a..417a17d96 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -10,7 +10,7 @@
         background: #121721;
         height: 25px;
         width: 25px;
-        right: 0;
+        right: 5px;
         display: flex;
         position: absolute;
         align-items: center;
@@ -18,6 +18,13 @@
         border-radius: 3px;
         pointer-events: all;
         z-index: 1; // so it appears on top of the document's title, if shown
+
+        box-shadow: $standard-box-shadow;
+        transition: 0.2s;
+
+        &:hover{
+            filter: brightness(0.85);
+        }
     }
 
     .pdfViewerDash-dragAnnotationBox {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 719e5a796..1f85219d6 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -33,6 +33,7 @@ import { FieldView, FieldViewProps } from './FieldView';
 import { LinkDocPreview } from "./LinkDocPreview";
 import "./WebBox.scss";
 import React = require("react");
+import { Colors } from "../global/globalEnums";
 const _global = (window /* browser */ || global /* node */) as any;
 const htmlToText = require("html-to-text");
 
@@ -590,11 +591,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                     moveDocument={this.moveDocument}
                     removeDocument={this.removeDocument}
                 />
-                <button className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
-                    style={{ display: !this.props.isContentActive() ? "none" : undefined }}
+                <div className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
+                    style={{ 
+                        display: !this.props.isContentActive() ? "none" : undefined, 
+                        top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5,
+                        backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK
+                    }}
                     onPointerDown={this.sidebarBtnDown} >
-                    <FontAwesomeIcon style={{ color: "white" }} icon={"chevron-left"} size="sm" />
-                </button>
+                        <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" />
+                </div>
             </div>);
     }
 }
diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/button/FontIconBox.scss
index 48fb2c8dc..a2da35fe1 100644
--- a/src/client/views/nodes/button/FontIconBox.scss
+++ b/src/client/views/nodes/button/FontIconBox.scss
@@ -7,6 +7,7 @@
     align-items: center;
     font-size: 80%;
     border-radius: $standard-border-radius;
+    transition: 0.15s;
 
     .menuButton-wrap {
         grid-column: 1;
@@ -29,6 +30,9 @@
         font-family: 'ROBOTO';
         text-transform: uppercase;
         font-weight: bold;
+        transition: 0.15s;
+
+
     }
 
     .fontIconBox-icon {
@@ -50,7 +54,18 @@
     }
 
     &.textBtn {
+        display: grid;
+        /* grid-row: auto; */
+        grid-auto-flow: column;
+        cursor: pointer;
         width: 100%;
+        justify-content: center;
+        align-items: center;
+        justify-items: center;
+
+        &:hover {
+            filter:brightness(0.85) !important;
+        }
     }
 
     &.tglBtn {
@@ -127,13 +142,13 @@
         }
 
         &:hover {
-            background-color: rgba(0, 0, 0, 0.3) !important;
+            background-color: rgba(0, 0, 0, 0.3);
         }
     }
 
     &.toolBtn {
         cursor: pointer;
-        width: 40px;
+        width: 100%;
         border-radius: 100%;
 
         svg {
@@ -143,7 +158,7 @@
     }
 
     &.menuBtn {
-        cursor: pointer;
+        cursor: pointer !important;
         border-radius: 0px;
         flex-direction: column;
 
@@ -151,6 +166,10 @@
             width: 45% !important;
             height: 45%;
         }
+        
+        &:hover{
+            filter: brightness(0.85);
+        }
     }
 
 
@@ -163,8 +182,8 @@
 
         .colorButton-color {
             margin-top: 3px;
-            width: 90%;
-            height: 6px;
+            width: 80%;
+            height: 3px;
         }
 
         .menuButton-dropdownBox {
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index bccf733f0..1b27d562a 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -253,11 +253,12 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
             } else if (selected) {
                 dropdown = false;
                 text = StrCast(selected.Document.type);
+                if (text === DocumentType.RTF) text = "Text";
                 icon = Doc.toIcon(selected.Document);
             } else {
                 dropdown = false;
-                noneSelected = true;
-                text = "None selected";
+                icon = "globe-asia";
+                text = "User Default";
             }
             noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
         } else if (script === 'setFont') {
@@ -302,7 +303,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
             <div className={`menuButton ${this.type} ${active}`}
                 style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
                 onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
-                {dropdown || noneSelected ? (null) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
+                {dropdown || noneSelected ? (null) : <FontAwesomeIcon style={{marginLeft: 5}} className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
                 <div className="menuButton-dropdown-header">
                     {text && text[0].toUpperCase() + text.slice(1)}
                 </div>
@@ -487,7 +488,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
             </div>;
 
         const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
-            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
+            <div className="fontIconBox-label" style={{ color: color, backgroundColor: "transparent" }}>
                 {this.label}
             </div>;
 
@@ -508,7 +509,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         switch (this.type) {
             case ButtonType.TextButton:
                 button = (
-                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1 }}>
+                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
                         <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                         {buttonText ? 
                             <div className="button-text">
@@ -558,7 +559,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 break;
             case ButtonType.MenuButton:
                 const trailsIcon = <img src={`/assets/${"presTrails.png"}`}
-                    style={{ width: 20, height: 20, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
+                    style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
                 button = (
                     <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor }}>
                         {this.icon === "pres-trail" ? trailsIcon : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />}
@@ -605,7 +606,7 @@ Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: bo
 Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
     const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
     if (checkResult && selected) {
-        if (NumCast(selected.Document.z) === 1) return Colors.MEDIUM_BLUE;
+        if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE;
         else return "transparent";
     }
     selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 3cedab1a4..56f5c5631 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -66,14 +66,25 @@ audiotag:hover {
     
 .formattedTextBox-sidebar-handle {
     position: absolute;
-    top: 0;
+    top: 5px;
     //top: calc(50% - 17.5px);  // use this to center vertically -- make sure it looks okay for slide views
-    width: 10px;
+    width: 25px;
     height: 100%;
-    max-height: 35px;
-    background: lightgray;
-    border-radius: 20px;
+    max-height: 25px;
+    color: white;
+    background: $medium-gray;
+    border-radius: 5px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
     cursor:grabbing;
+    box-shadow: $standard-box-shadow;
+    // transition: 0.2s;
+
+    &:hover{
+        filter: brightness(0.85);
+    }
+
 }
 
 .formattedTextBox-sidebar,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f45b9de7a..468edf6cc 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -63,6 +63,8 @@ import { SummaryView } from "./SummaryView";
 import applyDevTools = require("prosemirror-dev-tools");
 import React = require("react");
 import { SidebarAnnos } from '../../SidebarAnnos';
+import { Colors } from '../../global/globalEnums';
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
 const translateGoogleApi = require("translate-google-api");
 
 export interface FormattedTextBoxProps {
@@ -574,11 +576,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         changeItems.push({ description: "plain", event: undoBatch(() => Doc.setNativeView(this.rootDoc)), icon: "eye" });
         const noteTypesDoc = Cast(Doc.UserDoc()["template-notes"], Doc, null);
         DocListCast(noteTypesDoc?.data).forEach(note => {
+            const icon: IconProp = StrCast(note.icon) as IconProp;
             changeItems.push({
                 description: StrCast(note.title), event: undoBatch(() => {
                     Doc.setNativeView(this.rootDoc);
                     DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.TreeDocument, StrCast(note.title), note);
-                }), icon: "eye"
+                }), icon: icon
             });
         });
         !Doc.UserDoc().noviceMode && changeItems.push({ description: "FreeForm", event: () => DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), icon: "eye" });
@@ -1481,11 +1484,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     @computed get sidebarHandle() {
         TraceMobx();
         const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
+        const color = !annotated ? Colors.WHITE : Colors.BLACK;
+        const backgroundColor = !annotated ? this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""));
         return (!annotated && !this.props.isContentActive()) ? (null) : <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
             style={{
-                left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
-                background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
-            }} />;
+                left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${"- 30px"}))`,
+                backgroundColor: backgroundColor,
+                color: color
+            }} >
+                <FontAwesomeIcon icon={"comment-alt"}/>
+            </div>;
     }
     @computed get sidebarCollection() {
         const renderComponent = (tag: string) => {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 260ddfc90..e70b2bc19 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -114,7 +114,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
             const linkFrom = this.props.linkFrom();
             if (linkFrom) {
                 console.log(linkFrom.title);
-                DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo });
+                DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo }, "Link");
             }
         }
     });
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
index 05aeb177c..923f1892e 100644
--- a/src/client/views/topbar/TopBar.scss
+++ b/src/client/views/topbar/TopBar.scss
@@ -33,12 +33,12 @@
             align-self: center;
             border-radius: $standard-border-radius;
             padding: 5px;
-            transition: linear 0.1s;
+            transition: linear 0.2s;
             color: $black;
             background-color: $light-gray;
 
             &:hover {
-                background-color: $light-blue;
+                background-color: darken($color: $light-gray, $amount: 20);
             }
         }
 
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 4dbd5e22c..d5254e315 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -51,7 +51,8 @@ export class TopBar extends React.Component {
                         </div>
                     </div>
                     <div className="topbar-right" >
-                        <div className="topbar-icon">
+                        <div className="topbar-icon" onClick={() => window.open(
+                            "https://brown-dash.github.io/Dash-Documentation/", "_blank")}>
                             {"Help"}<FontAwesomeIcon icon="question-circle"></FontAwesomeIcon>
                         </div>
                         <div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}>
-- 
cgit v1.2.3-70-g09d2


From aee30b5ffc52e90559fa3c1786ce477943abcfb3 Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Thu, 2 Sep 2021 06:23:15 -0400
Subject: Placing collection menu in Lightbox (commented out) and others

- Set toggle properties off
- added link that goes directly to the dash documentation
---
 src/client/util/CurrentUserUtils.ts                | 36 ++++++++++++++--------
 src/client/views/LightboxView.tsx                  |  3 ++
 src/client/views/MainView.tsx                      | 12 ++++----
 src/client/views/PropertiesButtons.scss            |  9 +++---
 src/client/views/PropertiesButtons.tsx             |  8 ++---
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 src/client/views/nodes/button/FontIconBox.tsx      |  4 ++-
 src/client/views/nodes/trails/PresBox.tsx          |  4 +--
 8 files changed, 47 insertions(+), 31 deletions(-)

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

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index f6ec74482..56807c63b 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -55,6 +55,7 @@ interface Button {
     width?: number;
     list?: string[];
     ignoreClick?: boolean;
+    buttonText?: string;
 }
 
 export let resolvedPorts: { server: number, socket: number };
@@ -830,16 +831,17 @@ export class CurrentUserUtils {
     static async setupPresentations(doc: Doc) {
         await doc.myTrails;
         if (doc.myTrails === undefined) {
+            const newTrail = ScriptField.MakeScript(`createNewPresentation()`);
+            const newTrailButton:Doc = Docs.Create.FontIconDocument({ onClick: newTrail, _forceActive: true, toolTip: "New trail", _stayInCollection: true, _hideContextMenu: true, title: "New trail", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New trail", icon: "plus", system: true });
             doc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
                 title: "My Trails", _showTitle: "title", _height: 100,
-                treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
-                treeViewTruncateTitleWidth: 150, ignoreClick: true,
-                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
+                treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _fitWidth: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
+                treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newTrailButton,
+                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
+                explainer: "All of the trails that you have created will appear here."
             }));
-            const newPresentations = ScriptField.MakeScript(`createNewPresentation()`);
-            (doc.myTrails as any as Doc).contextMenuScripts = new List<ScriptField>([newPresentations!]);
+            (doc.myTrails as any as Doc).contextMenuScripts = new List<ScriptField>([newTrail!]);
             (doc.myTrails as any as Doc).contextMenuLabels = new List<string>(["Create New Trail"]);
-            const presentations = doc.myTrails as any as Doc;
         }
         return doc.myTrails as any as Doc;
     }
@@ -848,14 +850,19 @@ export class CurrentUserUtils {
         await doc.myFilesystem;
         if (doc.myFilesystem === undefined) {
             doc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
-            doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true });
-            doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileRoot as Doc, doc.myFileOrphans as Doc], {
-                title: "My Documents", _showTitle: "title", _height: 100,
+            // doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true });
+            const newFolder = ScriptField.MakeFunction(`doc.makeFolder()`, { doc: doc.myFilesystem })!;
+            const newFolderButton:Doc = Docs.Create.FontIconDocument({ onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true });
+            doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileOrphans as Doc], {
+                title: "My Documents", _showTitle: "title",  buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true,
-                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true
+                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
+                explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
             }));
+            (doc.myTrails as any as Doc).contextMenuScripts = new List<ScriptField>([newFolder!]);
+            (doc.myTrails as any as Doc).contextMenuLabels = new List<string>(["Create new folder"]);
         }
         return doc.myFilesystem as any as Doc;
     }
@@ -869,7 +876,7 @@ export class CurrentUserUtils {
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
-                explainer: "Documents that you close will appear here so you can easily access them again. You can choose to clear this menu in which case you might lose these documents."
+                explainer: "Recently closed documents appear in this menu. They will only be deleted if you explicity empty this list."
 
             }));
             (doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List<ScriptField>([clearAll!]);
@@ -1004,6 +1011,9 @@ export class CurrentUserUtils {
                     title: "Show preview",
                     toolTip: "Show preview of selected document",
                     btnType: ButtonType.ToggleButton,
+                    switchToggle: true,
+                    width: 100,
+                    buttonText: "Show Preview",
                     icon: "eye",
                     click: 'toggleSchemaPreview()',
                     checkResult: 'toggleSchemaPreview(true)'
@@ -1184,7 +1194,7 @@ export class CurrentUserUtils {
                     title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
                     _showTitle: "title", treeViewHideTitle: true, ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
                     _chromeHidden: true, boxShadow: "0 0",
-                    explainer: "All of the documents that you receive will appear here. They must be shared by other users. If you receive a Dashboard you can add it to your Dashboards by right clicking and clicking 'Add to Dashboards'"
+                    explainer: "This is where documents or dashboards that other users have shared with you will appear."
                 }, sharingDocumentId + "outer", sharingDocumentId);
                 (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Augment;
             }
@@ -1209,7 +1219,7 @@ export class CurrentUserUtils {
             doc.myUploadDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
                 title: "My Uploads", _forceActive: true, buttonMenu: true, buttonMenuDoc: newUploadButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
                 childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
-                explainer: "All of the documents that are imported into Dash will go here and stay here unless they are explicitly removed."
+                explainer: "This is where documents that are uploaded into Dash will go."
             }));
         }
     }
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 88739fe91..ec30a6a5d 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -16,6 +16,7 @@ import { TabDocView } from './collections/TabDocView';
 import "./LightboxView.scss";
 import { DocumentView } from './nodes/DocumentView';
 import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
+import { CollectionMenu } from './collections/CollectionMenu';
 
 interface LightboxViewProps {
     PanelWidth: number;
@@ -213,6 +214,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                         LightboxView.SetLightboxDoc(undefined);
                     }
                 }}  >
+                
                 <div className="lightboxView-contents" style={{
                     left: this.leftBorder,
                     top: this.topBorder,
@@ -220,6 +222,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                     height: this.lightboxHeight(),
                     clipPath: `path('${Doc.UserDoc().renderStyle === "comic" ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`
                 }}>
+                    {/* <CollectionMenu /> TODO:glr This is where it would go*/}
                     <DocumentView ref={action((r: DocumentView | null) => {
                         LightboxView._docView = r !== null ? r : undefined;
                         r && setTimeout(action(() => {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 9047951ee..440bb6bd5 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -173,7 +173,7 @@ export class MainView extends React.Component {
             fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical,
             fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll,
             fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines,
-            fa.faSave, fa.faBookmark, fa.faList, fa.faListOl);
+            fa.faSave, fa.faBookmark, fa.faList, fa.faListOl, fa.faFolderPlus, fa.faLightbulb, fa.faBookOpen);
         this.initAuthenticationRouters();
     }
 
@@ -227,16 +227,16 @@ export class MainView extends React.Component {
 
     @action
     createNewPresentation = async () => {
-        if (!await this.userDoc.myPresentations) {
-            this.userDoc.myPresentations = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "PRESENTATION TRAILS", childDontRegisterViews: true, _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true
+        if (!await this.userDoc.myTrails) {
+            this.userDoc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
+                title: "TRAILS", childDontRegisterViews: true, _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true
             }));
         }
         const pres = Docs.Create.PresDocument(new List<Doc>(),
-            { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
+            { title: "Untitled Trail", _viewType: CollectionViewType.Stacking, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
         CollectionDockingView.AddSplit(pres, "right");
         this.userDoc.activePresentation = pres;
-        Doc.AddDocToList(this.userDoc.myPresentations as Doc, "data", pres);
+        Doc.AddDocToList(this.userDoc.myTrails as Doc, "data", pres);
     }
 
     getPWidth = () => this._panelWidth - this.propertiesWidth();
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 77686a710..36b2df73e 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -44,14 +44,15 @@ $linkGap : 3px;
     }
 }
 .propertiesButtons-linkButton-empty.toggle-on {
-    background-color: white;
-    color: $dark-gray;
+    background-color: $medium-blue;
+    color: $white;
 }
 .propertiesButtons-linkButton-empty.toggle-hover {
-    background-color: gray;
-    color: $dark-gray;
+    background-color: $light-blue;
+    color: $black;
 }
 .propertiesButtons-linkButton-empty.toggle-off {
+    background-color: $dark-gray;
     color: white;
 }
 
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 4fde1124f..286365fa6 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -66,10 +66,10 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         return this.propertyToggleBtn("Lock\xA0View", "_lockedTransform", on => `${on ? "Unlock" : "Lock"} panning of view`, on => "lock");
     }
     @computed get fitContentButton() {
-        return this.propertyToggleBtn("View All", "_fitToBox", on => `${on ? "Don't" : ""} fit content to container visible area`, on => "eye");
+        return this.propertyToggleBtn("View All", "_fitToBox", on => `${on ? "Don't" : "Do"} fit content to container visible area`, on => "eye");
     }
     @computed get fitWidthButton() {
-        return this.propertyToggleBtn("Fit\xA0Width", "_fitWidth", on => `${on ? "Don't" : ""} fit content to width of container`, on => "arrows-alt-h");
+        return this.propertyToggleBtn("Fit\xA0Width", "_fitWidth", on => `${on ? "Don't" : "Do"} fit content to width of container`, on => "arrows-alt-h");
     }
     @computed get captionButton() {
         return this.propertyToggleBtn("Caption", "_showCaption", on => `${on ? "Hide" : "Show"} caption footer`, on => "closed-captioning", (dv, doc) => (dv?.rootDoc || doc)._showCaption = (dv?.rootDoc || doc)._showCaption === undefined ? "caption" : undefined);
@@ -211,13 +211,13 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 {toggle(this.titleButton)}
                 {toggle(this.captionButton)}
                 {toggle(this.lockButton)}
-                {toggle(this.dictationButton)}
+                {toggle(this.dictationButton, { display: isNovice ? "none" : "" })}
                 {toggle(this.onClickButton)}
                 {toggle(this.fitWidthButton, { display: isNovice ? "none" : "" })}
                 {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })}
                 {toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })}
                 {toggle(this.maskButton, { display: !isInk ? "none" : "" })}
-                {toggle(this.chromeButton, { display: isCollection ? "" : "none" })}
+                {toggle(this.chromeButton, { display: !isCollection || isNovice ? "none" : "" })}
                 {toggle(this.gridButton, { display: isCollection ? "" : "none" })}
                 {toggle(this.snapButton, { display: isCollection ? "" : "none" })}
                 {toggle(this.clustersButton, { display: !isFreeForm ? "none" : "" })}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 3c9084f64..c92b259d0 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -579,7 +579,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             <>
                 {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
                     {buttonMenu ? this.buttonMenu : null}
-                    {Doc.UserDoc().isNovice && noviceExplainer ? 
+                    {Doc.UserDoc().noviceMode && noviceExplainer ? 
                         <div className="documentExplanation">
                             {noviceExplainer}
                         </div>
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 1b27d562a..b72f31ef8 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -400,7 +400,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
     @computed get toggleButton() {
         // Determine the type of toggle button
         const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
-
+        const buttonText: string = StrCast(this.rootDoc.buttonText);
         // Colors
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
@@ -414,6 +414,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
         if (switchToggle) {
             return (
                 <div className={`menuButton ${this.type} ${'switch'}`}>
+                    {buttonText ? buttonText : null}
                     <label className="switch">
                         <input type="checkbox"
                             checked={backgroundColor === Colors.MEDIUM_BLUE}
@@ -880,6 +881,7 @@ Scripting.addGlobal(function webSetURL(url: string, checkResult?: boolean) {
  **/
 Scripting.addGlobal(function toggleSchemaPreview(checkResult?: boolean) {
     const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+    console.log(selected && selected.title);
     if (checkResult && selected) {
         const result: boolean = NumCast(selected.schemaPreviewWidth) > 0;
         if (result) return Colors.MEDIUM_BLUE;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index b805aa6ae..1abe26c20 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -167,7 +167,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.layoutDoc._yMargin = 0;
         this.turnOffEdit(true);
         DocListCastAsync((Doc.UserDoc().myTrails as Doc).data).then(pres =>
-            !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc));
+            !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myTrails as Doc, "data", this.rootDoc));
         this._disposers.selection = reaction(() => SelectionManager.Views(),
             views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation());
     }
@@ -2229,7 +2229,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const isMini: boolean = this.toolbarWidth <= 100;
         return (
             <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? "none" : undefined }}>
-                {isMini ? (null) : <select className="presBox-viewPicker"
+                {isMini || Doc.UserDoc().noviceMode ? (null) : <select className="presBox-viewPicker"
                     style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }}
                     onPointerDown={e => e.stopPropagation()}
                     onChange={this.viewChanged}
-- 
cgit v1.2.3-70-g09d2


From 57501970d9b56ed39c6b29680286d66a536df5f1 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 8 Sep 2021 18:55:32 -0400
Subject: added showTitle prop to allow sidebarAnnos to have a custom title

---
 src/client/views/SidebarAnnos.tsx                         | 10 ++--------
 src/client/views/StyleProvider.tsx                        |  9 ++++++---
 src/client/views/collections/CollectionStackingView.tsx   | 15 ++++++++-------
 .../collections/CollectionStackingViewFieldColumn.tsx     |  2 +-
 src/client/views/collections/CollectionView.tsx           |  1 +
 .../collectionFreeForm/CollectionFreeFormView.tsx         |  1 +
 src/client/views/nodes/DocumentView.tsx                   | 15 +++++++++++----
 7 files changed, 30 insertions(+), 23 deletions(-)

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

diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 01b79ffd2..dd851c764 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -83,13 +83,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
     moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey);
     removeDocument = (doc: Doc | Doc[]) => this.props.removeDocument(doc, this.sidebarKey);
     docFilters = () => [...StrListCast(this.props.layoutDoc._docFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])];
-
-    sidebarStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps | DocumentViewProps>, property: string) => {
-        if (property === StyleProp.ShowTitle) {
-            return doc === this.props.rootDoc ? undefined : StrCast(this.props.layoutDoc["sidebar-childShowTitle"], "title");
-        }
-        return this.props.styleProvider?.(doc, props, property);
-    }
+    showTitle = () => "title";
     setHeightCallback = (height: number) => this.props.setHeight(height + this.filtersHeight());
     render() {
         const renderTag = (tag: string) => {
@@ -125,13 +119,13 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
                         NativeHeight={returnZero}
                         PanelHeight={this.panelHeight}
                         PanelWidth={this.panelWidth}
-                        styleProvider={this.sidebarStyleProvider}
                         docFilters={this.docFilters}
                         scaleField={this.sidebarKey + "-scale"}
                         setHeight={this.setHeightCallback}
                         isAnnotationOverlay={false}
                         select={emptyFunction}
                         scaling={returnOne}
+                        childShowTitle={this.showTitle}
                         whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
                         childHideDecorationTitle={returnTrue}
                         removeDocument={this.removeDocument}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index e528e84e3..3413179ed 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -93,9 +93,12 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null));
         case StyleProp.HideLinkButton: return props?.hideLinkButton || (!selected && (doc?.isLinkButton || doc?.hideLinkButton));
         case StyleProp.FontSize: return StrCast(doc?.[fieldKey + "fontSize"]);
-        case StyleProp.ShowTitle: return doc && !doc.presentationTargetDoc && StrCast(doc._showTitle,
-            !Doc.IsSystem(doc) && doc.type === DocumentType.RTF ?
-                (doc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : "") || "";
+        case StyleProp.ShowTitle: return (doc && !doc.presentationTargetDoc &&
+            StrCast(doc._showTitle,
+                props?.showTitle?.() ||
+                (!Doc.IsSystem(doc) && doc.type === DocumentType.RTF ?
+                    (doc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) :
+                        "author;creationDate") : "")) || "");
         case StyleProp.Color:
             if (MainView.Instance.LastButton === doc) return Colors.DARK_GRAY;
             const docColor: Opt<string> = StrCast(doc?.[fieldKey + "color"], StrCast(doc?._color));
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c92b259d0..540bfd1ef 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -236,6 +236,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             dontCenter={this.props.childIgnoreNativeSize ? "xy" : undefined}
             dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)}
             rootSelected={this.rootSelected}
+            showTitle={this.props.childShowTitle}
             dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
             onClick={this.onChildClickHandler}
             onDoubleClick={this.onChildDoubleClickHandler}
@@ -517,14 +518,14 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
     }
 
     @computed get buttonMenu() {
-        const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
+        const menuDoc: Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
         // TODO:glr Allow support for multiple buttons
-        if (menuDoc){
+        if (menuDoc) {
             const width: number = NumCast(menuDoc._width, 30);
             const height: number = NumCast(menuDoc._height, 30);
             console.log(menuDoc.title, width, height);
             return (<div className="buttonMenu-docBtn"
-                style = {{width: width, height: height}}>
+                style={{ width: width, height: height }}>
                 <DocumentView
                     Document={menuDoc}
                     DataDoc={menuDoc}
@@ -550,7 +551,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                     docRangeFilters={this.props.docRangeFilters}
                     searchFilterDocs={this.props.searchFilterDocs}
                     ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined} 
+                    ContainingCollectionDoc={undefined}
                 />
             </div>
             );
@@ -579,7 +580,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             <>
                 {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
                     {buttonMenu ? this.buttonMenu : null}
-                    {Doc.UserDoc().noviceMode && noviceExplainer ? 
+                    {Doc.UserDoc().noviceMode && noviceExplainer ?
                         <div className="documentExplanation">
                             {noviceExplainer}
                         </div>
@@ -612,10 +613,10 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                                 checkedChildren="edit"
                                 unCheckedChildren="view"
                             />} */}
-                    </div> 
+                    </div>
                 </div>
             </>
-            
+
         );
     }
 }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 47733994b..58289a161 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -111,7 +111,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = "#b4b4b4");
     @action pointerLeave = () => this._background = "inherit";
-    textCallback = (char: string) => this.addNewTextDoc("", false, true);
+    textCallback = (char: string) => this.addNewTextDoc("-typed text-", false, true);
 
     @action
     addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 81375e557..bc02c44f0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -71,6 +71,7 @@ export interface CollectionViewProps extends FieldViewProps {
     childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox)
     childDocumentsActive?: () => boolean;// whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode)
     childFitWidth?: () => boolean;
+    childShowTitle?: () => string;
     childOpacity?: () => number;
     childContextMenuItems?: () => { script: ScriptField, label: string }[];
     childHideTitle?: () => boolean; // whether to hide the documentdecorations title for children
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 018c2a895..c8561d901 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1052,6 +1052,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             freezeDimensions={this.props.childFreezeDimensions}
             dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
             bringToFront={this.bringToFront}
+            showTitle={this.props.childShowTitle}
             dontRegisterView={this.props.dontRenderDocuments || this.props.dontRegisterView}
             pointerEvents={this.backgroundActive || this.props.childPointerEvents ? "all" :
                 (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : undefined}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 07e0e2d52..6eeb51ffe 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -114,6 +114,7 @@ export interface DocumentViewSharedProps {
     docFilters: () => string[];
     docRangeFilters: () => string[];
     searchFilterDocs: () => Doc[];
+    showTitle?: () => string;
     whenChildContentsActiveChanged: (isActive: boolean) => void;
     rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected
     addDocTab: (doc: Doc, where: string) => boolean;
@@ -703,9 +704,11 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
 
                 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.rootDoc, false)), icon: "expand-arrows-alt" });
-                zorderItems.push({ description: "Send to Back", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" });
-                zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: undoBatch(action(() => this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined)), icon: "expand-arrows-alt" });
+                if (this.props.bringToFront !== emptyFunction) {
+                    zorderItems.push({ description: "Bring to Front", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, false)), icon: "expand-arrows-alt" });
+                    zorderItems.push({ description: "Send to Back", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" });
+                    zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: undoBatch(action(() => this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined)), icon: "expand-arrows-alt" });
+                }
                 !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" });
 
                 onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
@@ -974,7 +977,11 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                             if (showTitle.includes("Date") || showTitle === "author") return true;
                             return Doc.SetInPlace(targetDoc, showTitle, value, true) ? true : true;
                         } else if (value?.startsWith("#")) {
-                            Doc.UserDoc().showTitle = value?.substring(1) ? value.substring(1) : "creationDate";
+                            if (this.props.showTitle) {
+                                this.rootDoc._showTitle = value?.substring(1) ? value.substring(1) : undefined;
+                            } else {
+                                Doc.UserDoc().showTitle = value?.substring(1) ? value.substring(1) : "creationDate";
+                            }
                             return true;
                         }
                         return true;
-- 
cgit v1.2.3-70-g09d2

