From 36630b9aa2e1c4710a69a4fdf4ec98c3f5bca92c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 21 Aug 2020 16:05:52 -0400
Subject: trying scenes instead of workspaces

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

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 0cc492ee9..fdce8bf71 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -596,7 +596,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         return <FontAwesomeIcon icon={button} className="documentView-minimizedIcon" />;
     }
     render() {
-        const darkScheme = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimgray" : undefined;
+        const darkScheme = Cast(Doc.UserDoc().activeScene, Doc, null)?.darkScheme ? "dimgray" : undefined;
         const bounds = this.Bounds;
         const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined;
         if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
-- 
cgit v1.2.3-70-g09d2


From ca9cf672bdfd8ebf11cb20264474bcb9d9729944 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 21 Aug 2020 18:46:58 -0400
Subject: switched from "scenes" to "dashboards"

---
 src/client/documents/Documents.ts                  |  4 +-
 src/client/util/CurrentUserUtils.ts                | 40 ++++++-------
 src/client/util/History.ts                         |  2 +-
 src/client/util/SettingsManager.tsx                |  2 +-
 src/client/views/DocumentDecorations.tsx           |  2 +-
 src/client/views/MainView.scss                     |  2 +-
 src/client/views/MainView.tsx                      | 50 ++++++++--------
 .../views/collections/CollectionDockingView.tsx    | 35 ++++++-----
 .../views/collections/CollectionTreeView.tsx       |  8 +--
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../CollectionFreeFormLayoutEngines.tsx            |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  8 +--
 .../views/nodes/formattedText/DashDocView.tsx      |  4 +-
 .../views/nodes/formattedText/RichTextSchema.tsx   |  4 +-
 src/mobile/MobileInterface.tsx                     | 70 +++++++++++-----------
 15 files changed, 120 insertions(+), 115 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 7d114d417..697ff858f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -820,7 +820,9 @@ export namespace Docs {
 
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
             const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
-            Doc.GetProto(inst).data = new List<Doc>(documents);
+            const tabs = TreeDocument(documents, { title: "Active Tabs" });
+            const all = TreeDocument([], { title: "Other Tabs" });
+            Doc.GetProto(inst).data = new List<Doc>([tabs, all]);
             return inst;
         }
 
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 4b1c48bd3..b439b8b43 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -36,7 +36,7 @@ export class CurrentUserUtils {
     @computed public static get UserDocument() { return Doc.UserDoc(); }
 
     @observable public static GuestTarget: Doc | undefined;
-    @observable public static GuestScene: Doc | undefined;
+    @observable public static GuestDashboard: Doc | undefined;
     @observable public static GuestMobile: Doc | undefined;
 
     @observable public static propertiesWidth: number = 0;
@@ -510,11 +510,11 @@ export class CurrentUserUtils {
     }[] {
         this.setupSharingSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
         return [
-            { title: "Sharing", target: Cast(doc["sidebar-sharing"], Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc["sidebar-sharing"] as Doc },
-            { title: "Scenes", target: Cast(doc["sidebar-scenes"], Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
+            { title: "Dashboards", target: Cast(doc["sidebar-dashboards"], Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
             { title: "Catalog", target: undefined as any, icon: "file", click: 'selectMainMenu(self)' },
             { title: "Archive", target: Cast(doc["sidebar-recentlyClosed"], Doc, null), icon: "archive", click: 'selectMainMenu(self)' },
             { title: "Import", target: Cast(doc["sidebar-import"], Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
+            { title: "Sharing", target: Cast(doc["sidebar-sharing"], Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc["sidebar-sharing"] as Doc },
             { title: "Tools", target: Cast(doc["sidebar-tools"], Doc, null), icon: "wrench", click: 'selectMainMenu(self)' },
             { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' },
             { title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' },
@@ -592,7 +592,7 @@ export class CurrentUserUtils {
     // SEts up mobile buttons for inside mobile menu
     static setupMobileButtons(doc?: Doc, buttons?: string[]) {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
-            { title: "SCENES", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Scenes from your mobile, and navigate through all of your documents. " },
+            { title: "SCENES", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Dashboards from your mobile, and navigate through all of your documents. " },
             { title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
             { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploadCollection()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." },
             { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." },
@@ -689,7 +689,7 @@ export class CurrentUserUtils {
     }
 
     static setupLibrary(userDoc: Doc) {
-        return CurrentUserUtils.setupScenes(userDoc);
+        return CurrentUserUtils.setupDashboards(userDoc);
     }
 
     // setup the Creator button which will display the creator panel.  This panel will include the drag creators and the color picker. 
@@ -724,28 +724,28 @@ export class CurrentUserUtils {
         }
     }
 
-    static async setupScenes(doc: Doc) {
-        // setup scenes library item
-        await doc.myScenes;
-        if (doc.myScenes === undefined) {
-            doc.myScenes = new PrefetchProxy(Docs.Create.TreeDocument([], {
+    static async setupDashboards(doc: Doc) {
+        // setup dashboards library item
+        await doc.myDashboards;
+        if (doc.myDashboards === undefined) {
+            doc.myDashboards = new PrefetchProxy(Docs.Create.TreeDocument([], {
                 title: "SCENES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true, system: true
             }));
         }
-        if (doc["sidebar-scenes"] === undefined) {
-            const newScene = ScriptField.MakeScript(`createNewScene()`);
-            (doc.myScenes as Doc).contextMenuScripts = new List<ScriptField>([newScene!]);
-            (doc.myScenes as Doc).contextMenuLabels = new List<string>(["Create New Scene"]);
+        if (doc["sidebar-dashboards"] === undefined) {
+            const newDashboard = ScriptField.MakeScript(`createNewDashboard()`);
+            (doc.myDashboards as Doc).contextMenuScripts = new List<ScriptField>([newDashboard!]);
+            (doc.myDashboards as Doc).contextMenuLabels = new List<string>(["Create New Dashboard"]);
 
-            const scenes = doc.myScenes as Doc;
+            const dashboards = doc.myDashboards as Doc;
 
-            doc["sidebar-scenes"] = new PrefetchProxy(Docs.Create.TreeDocument([scenes], {
+            doc["sidebar-dashboards"] = new PrefetchProxy(Docs.Create.TreeDocument([dashboards], {
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
                 lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
             })) as any as Doc;
         }
-        return doc.myScenes as any as Doc;
+        return doc.myDashboards as any as Doc;
     }
 
     static setupCatalog(doc: Doc) {
@@ -821,7 +821,7 @@ export class CurrentUserUtils {
     static async setupSidebarButtons(doc: Doc) {
         CurrentUserUtils.setupSidebarContainer(doc);
         await CurrentUserUtils.setupToolsBtnPanel(doc);
-        CurrentUserUtils.setupScenes(doc);
+        CurrentUserUtils.setupDashboards(doc);
         CurrentUserUtils.setupCatalog(doc);
         CurrentUserUtils.setupRecentlyClosed(doc);
         CurrentUserUtils.setupUserDoc(doc);
@@ -1002,8 +1002,8 @@ export class CurrentUserUtils {
     }
 }
 
-Scripting.addGlobal(function createNewScene() { return MainView.Instance.createNewScene(); },
-    "creates a new scene when called");
+Scripting.addGlobal(function createNewDashboard() { return MainView.Instance.createNewDashboard(); },
+    "creates a new dashboard when called");
 
 Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
     "returns all the links to the document or its annotations", "(doc: any)");
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index aed887055..cab682ac7 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -197,7 +197,7 @@ export namespace HistoryUtil {
             await Promise.all(Object.keys(init).map(id => initDoc(id, init[id])));
         }
         if (field instanceof Doc) {
-            MainView.Instance.openScene(field, true);
+            MainView.Instance.openDashboard(field, true);
         }
     }
 
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index b2131c9b2..accb9c346 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -158,7 +158,7 @@ export default class SettingsManager extends React.Component<{}> {
                 <div className="settings-title">Settings</div>
                 <div className="settings-username">{Doc.CurrentUserEmail}</div>
                 <button className="logout-button" onClick={() => window.location.assign(Utils.prepend("/logout"))} >
-                    {CurrentUserUtils.GuestScene ? "Exit" : "Log Out"}
+                    {CurrentUserUtils.GuestDashboard ? "Exit" : "Log Out"}
                 </button>
                 <div className="close-button" onClick={this.close}>
                     <FontAwesomeIcon icon={fa.faTimes} color="black" size={"lg"} />
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index fdce8bf71..c44c2968c 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -596,7 +596,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         return <FontAwesomeIcon icon={button} className="documentView-minimizedIcon" />;
     }
     render() {
-        const darkScheme = Cast(Doc.UserDoc().activeScene, Doc, null)?.darkScheme ? "dimgray" : undefined;
+        const darkScheme = Cast(Doc.UserDoc().activeDashboard, Doc, null)?.darkScheme ? "dimgray" : undefined;
         const bounds = this.Bounds;
         const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined;
         if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index fb80bfc0d..2d742f4ba 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -313,7 +313,7 @@
 
 }
 
-.mainView-scene {
+.mainView-dashboard {
     height: 200px;
     position: relative;
     display: flex;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 08ac69a38..64efc5ee5 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -77,10 +77,10 @@ export class MainView extends React.Component {
     @observable private _panelHeight: number = 0;
     @observable private _flyoutTranslate: boolean = false;
     @observable public flyoutWidth: number = 0;
-    private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeScene, Doc, null)?.darkScheme); }
+    private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeDashboard, Doc, null)?.darkScheme); }
 
     @computed private get userDoc() { return Doc.UserDoc(); }
-    @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeScene, Doc)) : CurrentUserUtils.GuestScene; }
+    @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeDashboard, Doc)) : CurrentUserUtils.GuestDashboard; }
     @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
     @computed public get searchDoc() { return Cast(this.userDoc["search-panel"], Doc) as Doc; }
 
@@ -224,12 +224,12 @@ export class MainView extends React.Component {
     }
 
     initAuthenticationRouters = async () => {
-        // Load the user's active scene, or create a new one if initial session after signup
+        // Load the user's active dashboard, or create a new one if initial session after signup
         const received = CurrentUserUtils.MainDocId;
         if (received && !this.userDoc) {
             reaction(
                 () => CurrentUserUtils.GuestTarget,
-                target => target && this.createNewScene(),
+                target => target && this.createNewDashboard(),
                 { fireImmediately: true }
             );
         } else {
@@ -242,21 +242,21 @@ export class MainView extends React.Component {
                     }),
                 );
             }
-            const doc = this.userDoc && await Cast(this.userDoc.activeScene, Doc);
+            const doc = this.userDoc && await Cast(this.userDoc.activeDashboard, Doc);
             if (doc) {
-                this.openScene(doc);
+                this.openDashboard(doc);
             } else {
-                this.createNewScene();
+                this.createNewDashboard();
             }
         }
     }
 
     @action
-    createNewScene = async (id?: string) => {
+    createNewDashboard = async (id?: string) => {
         const myCatalog = Doc.UserDoc().myCatalog as Doc;
         const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true);
-        const scenes = Cast(this.userDoc.myScenes, Doc) as Doc;
-        const sceneCount = DocListCast(scenes.data).length + 1;
+        const dashboards = Cast(this.userDoc.myDashboards, Doc) as Doc;
+        const dashboardCount = DocListCast(dashboards.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
@@ -265,28 +265,28 @@ export class MainView extends React.Component {
             title: "Untitled Collection",
         };
         const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
-        const sceneDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [myCatalog] }], { title: `Scene ${sceneCount}` }, id, "row");
+        const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [myCatalog] }], { title: `Dashboard ${dashboardCount}` }, id, "row");
         Doc.AddDocToList(myCatalog, "data", freeformDoc);
         Doc.AddDocToList(myCatalog, "data", presentation);
         Doc.UserDoc().activePresentation = presentation;
         const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
         const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
-        const copyScene = ScriptField.MakeScript(`copyScene()`);
-        sceneDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, copyScene!]);
-        sceneDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Scene"]);
+        const copyDashboard = ScriptField.MakeScript(`copyDashboard()`);
+        dashboardDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, copyDashboard!]);
+        dashboardDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard"]);
 
-        Doc.AddDocToList(scenes, "data", sceneDoc);
+        Doc.AddDocToList(dashboards, "data", dashboardDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
-        setTimeout(() => this.openScene(sceneDoc), 0);
+        setTimeout(() => this.openDashboard(dashboardDoc), 0);
     }
 
     @action
-    openScene = (doc: Doc, fromHistory = false) => {
+    openDashboard = (doc: Doc, fromHistory = false) => {
         CurrentUserUtils.MainDocId = doc[Id];
 
-        if (doc) {  // this has the side-effect of setting the main container since we're assigning the active/guest scene
+        if (doc) {  // this has the side-effect of setting the main container since we're assigning the active/guest dashboard
             !("presentationView" in doc) && (doc.presentationView = new List<Doc>([Docs.Create.TreeDocument([], { title: "Presentation" })]));
-            this.userDoc ? (this.userDoc.activeScene = doc) : (CurrentUserUtils.GuestScene = doc);
+            this.userDoc ? (this.userDoc.activeDashboard = doc) : (CurrentUserUtils.GuestDashboard = doc);
         }
         const state = this._urlState;
         if (state.sharing === true && !this.userDoc) {
@@ -438,7 +438,7 @@ export class MainView extends React.Component {
     flyoutWidthFunc = () => this.flyoutWidth;
     addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
         return where === "close" ? CollectionDockingView.CloseRightSplit(doc) :
-            doc.dockingConfig ? this.openScene(doc) :
+            doc.dockingConfig ? this.openDashboard(doc) :
                 CollectionDockingView.AddRightSplit(doc, libraryPath);
     }
     sidebarScreenToLocal = () => new Transform(0, (CollectionMenu.Instance.Pinned ? -35 : 0) - Number(SEARCH_PANEL_HEIGHT.replace("px", "")), 1);
@@ -977,12 +977,12 @@ export class MainView extends React.Component {
 }
 Scripting.addGlobal(function selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); });
 Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().fontFamily = "Comic Sans MS"; Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; });
-Scripting.addGlobal(function copyScene() {
-    const copiedScene = Doc.MakeCopy(Cast(Doc.UserDoc().activeScene, Doc, null), true);
-    const scenes = Cast(Doc.UserDoc().myScenes, Doc, null);
-    Doc.AddDocToList(scenes, "data", copiedScene);
+Scripting.addGlobal(function copyDashboard() {
+    const copiedDashboard = Doc.MakeCopy(Cast(Doc.UserDoc().activeDashboard, Doc, null), true);
+    const dashboards = Cast(Doc.UserDoc().myDashboards, Doc, null);
+    Doc.AddDocToList(dashboards, "data", copiedDashboard);
     // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
-    setTimeout(() => MainView.Instance.openScene(copiedScene), 0);
+    setTimeout(() => MainView.Instance.openDashboard(copiedDashboard), 0);
 });
 Scripting.addGlobal(function importDocument() { return MainView.Instance.importDocument(); },
     "imports files from device directly into the import sidebar");
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 6338e69a4..2f84065ec 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -31,9 +31,10 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV
 import { listSpec } from '../../../fields/Schema';
 import { clamp } from 'lodash';
 import { PresBox } from '../nodes/PresBox';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { InteractionUtils } from '../../util/InteractionUtils';
 import { InkTool } from '../../../fields/InkField';
+import { List } from '../../../fields/List';
+import { lstat } from 'fs';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -79,9 +80,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         } else {
             config = {
                 type: 'row',
-                content: dragDocs.map((doc, i) => {
-                    CollectionDockingView.makeDocumentConfig(doc);
-                })
+                content: dragDocs.map((doc, i) => CollectionDockingView.makeDocumentConfig(doc))
             };
         }
         const div = document.createElement("div");
@@ -96,7 +95,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @action
     public OpenFullScreen(docView: DocumentView, libraryPath?: Doc[]) {
         if (docView.props.Document._viewType === CollectionViewType.Docking && docView.props.Document.layoutKey === "layout") {
-            return MainView.Instance.openScene(docView.props.Document);
+            return MainView.Instance.openDashboard(docView.props.Document);
         }
         const document = Doc.MakeAlias(docView.props.Document);
         const newItemStackConfig = {
@@ -154,7 +153,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         this._goldenLayout.root.callDownwards('setSize', [this._goldenLayout.width, this._goldenLayout.height]);
         this._goldenLayout.emit('stateChanged');
         this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
-        if (removed) CollectionDockingView.Instance._removedDocs.push(removed);
         this.stateChanged();
     }
     @undoBatch
@@ -410,8 +408,8 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                         // Because this is in a set timeout, if this component unmounts right after mounting,
                         // we will leak a GoldenLayout, because we try to destroy it before we ever create it
                         setTimeout(() => this.setupGoldenLayout(), 1);
-                        DocListCast((Doc.UserDoc().myScenes as Doc).data).map(d => d.sceneBrush = false);
-                        this.props.Document.sceneBrush = true;
+                        DocListCast((Doc.UserDoc().myDashboards as Doc).data).map(d => d.dashboardBrush = false);
+                        this.props.Document.dashboardBrush = true;
                     }
                     this._ignoreStateChange = "";
                 }, { fireImmediately: true });
@@ -421,7 +419,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
     componentWillUnmount: () => void = () => {
         try {
-            this.props.Document.sceneBrush = false;
+            this.props.Document.dashboardBrush = false;
             this._goldenLayout.unbind('itemDropped', this.itemDropped);
             this._goldenLayout.unbind('tabCreated', this.tabCreated);
             this._goldenLayout.unbind('stackCreated', this.stackCreated);
@@ -481,8 +479,16 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
         if (docids) {
             const docs = (await Promise.all(docids.map(id => DocServer.GetRefField(id)))).filter(f => f).map(f => f as Doc);
-            docs.map(doc => Doc.AddDocToList(Doc.GetProto(this.props.Document), this.props.fieldKey, doc));
-            // Doc.GetProto(this.props.Document)[this.props.fieldKey] = new List<Doc>(docs);
+            const sublists = DocListCast(this.props.Document[this.props.fieldKey]);
+            const tabs = Cast(sublists[0], Doc, null);
+            const other = Cast(sublists[1], Doc, null);
+            const tabdocs = DocListCast(tabs.data);
+            const otherdocs = DocListCast(other.data);
+            Doc.GetProto(tabs).data = new List<Doc>(docs);
+            const otherSet = new Set<Doc>();
+            otherdocs.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
+            tabdocs.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
+            Doc.GetProto(other).data = new List<Doc>(Array.from(otherSet.values()));
         }
     }
 
@@ -586,7 +592,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                 const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId);
                 if (doc instanceof Doc) {
                     const theDoc = doc;
-                    CollectionDockingView.Instance._removedDocs.push(theDoc);
 
                     const recent = await Cast(Doc.UserDoc().myRecentlyClosed, Doc);
                     if (recent) {
@@ -607,7 +612,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             }
         }
     }
-    _removedDocs: Doc[] = [];
 
     stackCreated = (stack: any) => {
         //stack.header.controlsContainer.find('.lm_popout').hide();
@@ -652,7 +656,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                             Doc.AddDocToList(recent, "data", doc, undefined, true, true);
                         }
                         const theDoc = doc;
-                        CollectionDockingView.Instance._removedDocs.push(theDoc);
                     }
                 });
                 //}
@@ -668,7 +671,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
     render() {
         if (this.props.renderDepth > 0) {
-            return <div style={{ width: "100%", height: "100%" }}>Nested scenes can't be rendered</div>;
+            return <div style={{ width: "100%", height: "100%" }}>Nested dashboards can't be rendered</div>;
         }
         return <div className="collectiondockingview-container" id="menuContainer"
             onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} ref={this._containerRef} />;
@@ -834,7 +837,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     addDocTab = (doc: Doc, location: string, libraryPath?: Doc[]) => {
         SelectionManager.DeselectAll();
         if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === "layout") {
-            return MainView.Instance.openScene(doc);
+            return MainView.Instance.openDashboard(doc);
         } else if (location === "onRight") {
             return CollectionDockingView.AddRightSplit(doc, libraryPath);
         } else if (location === "close") {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6eead6e6d..b78678bc3 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -471,7 +471,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 style={{
                     fontWeight: this.doc.searchMatch !== undefined ? "bold" : undefined,
                     textDecoration: Doc.GetT(this.doc, "title", "string", true) ? "underline" : undefined,
-                    outline: BoolCast(this.doc.sceneBrush) ? "dashed 1px #06123232" : undefined,
+                    outline: BoolCast(this.doc.dashboardBrush) ? "dashed 1px #06123232" : undefined,
                     pointerEvents: this.props.active() || SnappingManager.GetIsDragging() ? undefined : "none"
                 }} >
                 {view}
@@ -725,9 +725,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
     }
     onContextMenu = (e: React.MouseEvent): void => {
         // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
-        if (!e.isPropagationStopped() && this.doc === Doc.UserDoc().myScenes) {
-            ContextMenu.Instance.addItem({ description: "Create Scene", event: () => MainView.Instance.createNewScene(), icon: "plus" });
-            ContextMenu.Instance.addItem({ description: "Delete Scene", event: () => this.remove(this.doc), icon: "minus" });
+        if (!e.isPropagationStopped() && this.doc === Doc.UserDoc().myDashboards) {
+            ContextMenu.Instance.addItem({ description: "Create Dashboard", event: () => MainView.Instance.createNewDashboard(), icon: "plus" });
+            ContextMenu.Instance.addItem({ description: "Delete Dashboard", event: () => this.remove(this.doc), icon: "minus" });
             e.stopPropagation();
             e.preventDefault();
             ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index c75179252..12d2152b1 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -588,7 +588,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             ChildLayoutString: this.childLayoutString,
         };
         const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
-            `${Cast(Doc.UserDoc().activeScene, Doc, null)?.darkScheme ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}`;
+            `${Cast(Doc.UserDoc().activeDashboard, Doc, null)?.darkScheme ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}`;
         return (<div className={"collectionView"} onContextMenu={this.onContextMenu}
             style={{ pointerEvents: this.props.Document.isBackground ? "none" : undefined, boxShadow }}>
             {this.showIsTagged()}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 6a320dfde..646ae94fb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -359,7 +359,7 @@ export function computeTimelineLayout(
         groupNames.push({ type: "text", text: toLabel(Math.ceil(maxTime)), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined });
     }
 
-    const divider = { type: "div", color: Cast(Doc.UserDoc().activeScene, Doc, null)?.darkScheme ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined };
+    const divider = { type: "div", color: Cast(Doc.UserDoc().activeDashboard, Doc, null)?.darkScheme ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined };
     return normalizeResults(panelDim, fontHeight, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]);
 
     function layoutDocsAtTime(keyDocs: Doc[], key: number) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8d9d1f729..91f12f004 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -564,8 +564,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @undoBatch @action
     deleteClicked = (): void => {
-        if (Doc.UserDoc().activeScene === this.props.Document) {
-            alert("Can't delete the active scene");
+        if (Doc.UserDoc().activeDashboard === this.props.Document) {
+            alert("Can't delete the active dashboard");
         } else {
             const selected = SelectionManager.SelectedDocuments().slice();
             SelectionManager.DeselectAll();
@@ -601,7 +601,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @undoBatch @action
     drop = async (e: Event, de: DragManager.DropEvent) => {
-        if (this.props.Document === Doc.UserDoc().activeScene) {
+        if (this.props.Document === Doc.UserDoc().activeDashboard) {
             alert("linking to document tabs not yet supported.  Drop link on document content.");
             return;
         }
@@ -1011,7 +1011,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document);
         const borderRounding = this.layoutDoc.borderRounding;
         const localScale = fullDegree;
-        const highlightColors = Cast(Doc.UserDoc().activeScene, Doc, null)?.darkScheme ?
+        const highlightColors = Cast(Doc.UserDoc().activeDashboard, Doc, null)?.darkScheme ?
             ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] :
             ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
         const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 0e965ba9a..31dd92b59 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -175,7 +175,7 @@ export class DashDocView extends React.Component<IDashDocView> {
         const outerStyle = {
             position: "relative" as "relative",
             textIndent: "0",
-            border: "1px solid " + StrCast(this._textBox.Document.color, (Cast(Doc.UserDoc().activeScene, Doc, null).darkScheme ? "dimGray" : "lightGray")),
+            border: "1px solid " + StrCast(this._textBox.Document.color, (Cast(Doc.UserDoc().activeDashboard, Doc, null).darkScheme ? "dimGray" : "lightGray")),
             width: this.props.node.props.width,
             height: this.props.node.props.height,
             display: this.props.node.props.hidden ? "none" : "inline-block",
@@ -202,7 +202,7 @@ export class DashDocView extends React.Component<IDashDocView> {
                 ({ dim, color }) => {
                     spanStyle.width = outerStyle.width = Math.max(20, dim[0]) + "px";
                     spanStyle.height = outerStyle.height = Math.max(20, dim[1]) + "px";
-                    outerStyle.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeScene, Doc, null).darkScheme ? "dimGray" : "lightGray"));
+                    outerStyle.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeDashboard, Doc, null).darkScheme ? "dimGray" : "lightGray"));
                 }, { fireImmediately: true });
 
             if (node.attrs.width !== dashDoc._width + "px" || node.attrs.height !== dashDoc._height + "px") {
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index 78c76efcb..a85dacc7e 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -43,7 +43,7 @@ export class DashDocView {
         this._outer = document.createElement("span");
         this._outer.style.position = "relative";
         this._outer.style.textIndent = "0";
-        this._outer.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (Cast(Doc.UserDoc().activeScene, Doc, null).darkScheme ? "dimGray" : "lightGray"));
+        this._outer.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (Cast(Doc.UserDoc().activeDashboard, Doc, null).darkScheme ? "dimGray" : "lightGray"));
         this._outer.style.width = node.attrs.width;
         this._outer.style.height = node.attrs.height;
         this._outer.style.display = node.attrs.hidden ? "none" : "inline-block";
@@ -126,7 +126,7 @@ export class DashDocView {
             this._reactionDisposer = reaction(() => ({ dim: [finalLayout[WidthSym](), finalLayout[HeightSym]()], color: finalLayout.color }), ({ dim, color }) => {
                 this._dashSpan.style.width = this._outer.style.width = Math.max(20, dim[0]) + "px";
                 this._dashSpan.style.height = this._outer.style.height = Math.max(20, dim[1]) + "px";
-                this._outer.style.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeScene, Doc, null).darkScheme ? "dimGray" : "lightGray"));
+                this._outer.style.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeDashboard, Doc, null).darkScheme ? "dimGray" : "lightGray"));
             }, { fireImmediately: true });
 
             const doReactRender = (finalLayout: Doc, resolvedDataDoc: Doc) => {
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index fc8c45c25..41b997285 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -58,7 +58,7 @@ export class MobileInterface extends React.Component {
     @observable private _menuListView: boolean = false; //to switch between menu view (list / icon)
     @observable private _ink: boolean = false; //toggle whether ink is being dispalyed
     @observable private _homeMenu: boolean = true; // to determine whether currently at home menu
-    @observable private scenes: Doc | null = null; // currently selected document
+    @observable private dashboards: Doc | null = null; // currently selected document
     @observable private _activeDoc: Doc = this._mainDoc; // doc updated as the active mobile page is updated (initially home menu)
     @observable private _homeDoc: Doc = this._mainDoc; // home menu as a document
     @observable private _parents: Array<Doc> = []; // array of parent docs (for pathbar)
@@ -136,19 +136,19 @@ export class MobileInterface extends React.Component {
     back = () => {
         const header = document.getElementById("header") as HTMLElement;
         const doc = Cast(this._parents.pop(), Doc) as Doc; // Parent document
-        // Case 1: Parent document is 'scenes'
+        // Case 1: Parent document is 'dashboards'
         if (doc === Cast(this._library, Doc) as Doc) {
-            this.scenes = null;
+            this.dashboards = null;
             this._library.then(library => this.switchCurrentView(library));
             // Case 2: Parent document is the 'home' menu (root node)
         } else if (doc === Cast(this._homeDoc, Doc) as Doc) {
             this._homeMenu = true;
             this._parents = [];
-            this.scenes = null;
+            this.dashboards = null;
             this.switchCurrentView(this._homeDoc);
             // Case 3: Parent document is any document
         } else if (doc) {
-            this.scenes = doc;
+            this.dashboards = doc;
             this.switchCurrentView(doc);
             this._homeMenu = false;
             header.textContent = String(doc.title);
@@ -164,7 +164,7 @@ export class MobileInterface extends React.Component {
         if (!this._homeMenu || this._sidebarActive) {
             this._homeMenu = true;
             this._parents = [];
-            this.scenes = null;
+            this.dashboards = null;
             this.switchCurrentView(this._homeDoc);
         }
         if (this._sidebarActive) {
@@ -173,14 +173,14 @@ export class MobileInterface extends React.Component {
     }
 
     /**
-     * Return to primary Scene in library (Scenes Doc)
+     * Return to primary Dashboard in library (Dashboards Doc)
      */
     @action
     returnMain = () => {
         this._parents = [this._homeDoc];
         this._library.then(library => this.switchCurrentView(library));
         this._homeMenu = false;
-        this.scenes = null;
+        this.dashboards = null;
     }
 
     /**
@@ -194,7 +194,7 @@ export class MobileInterface extends React.Component {
     /**
      * DocumentView for graphic display of all documents
      */
-    @computed get displayScenes() {
+    @computed get displayDashboards() {
         return !this.mainContainer ? (null) :
             <div style={{ position: "relative", top: '198px', height: `calc(100% - 350px)`, width: "100%", left: "0%" }}>
                 <DocumentView
@@ -243,7 +243,7 @@ export class MobileInterface extends React.Component {
                 this._parents.push(this._activeDoc);
                 this.switchCurrentView(doc);
                 this._homeMenu = false;
-                this.scenes = doc;
+                this.dashboards = doc;
             }
         });
     }
@@ -258,7 +258,7 @@ export class MobileInterface extends React.Component {
         this._parents.push(this._activeDoc);
         this.switchCurrentView(doc);
         this._homeMenu = false;
-        this.scenes = doc;
+        this.dashboards = doc;
         this.toggleSidebar();
     }
 
@@ -290,13 +290,13 @@ export class MobileInterface extends React.Component {
     handlePathClick = async (doc: Doc, index: number) => {
         const library = await this._library;
         if (doc === library) {
-            this.scenes = null;
+            this.dashboards = null;
             this.switchCurrentView(doc);
             this._parents.length = index;
         } else if (doc === this._homeDoc) {
             this.returnHome();
         } else {
-            this.scenes = doc;
+            this.dashboards = doc;
             this.switchCurrentView(doc);
             this._parents.length = index;
         }
@@ -321,13 +321,13 @@ export class MobileInterface extends React.Component {
                 </div>
             );
         }
-        // stores scenes documents as 'scenes' variable
-        let scenes = Cast(Doc.UserDoc().myScenes, Doc) as Doc;
-        if (this.scenes) {
-            scenes = this.scenes;
+        // stores dashboards documents as 'dashboards' variable
+        let dashboards = Cast(Doc.UserDoc().myDashboards, Doc) as Doc;
+        if (this.dashboards) {
+            dashboards = this.dashboards;
         }
         // returns a list of navbar buttons as 'buttons'
-        const buttons = DocListCast(scenes.data).map((doc: Doc, index: any) => {
+        const buttons = DocListCast(dashboards.data).map((doc: Doc, index: any) => {
             if (doc.type !== "ink") {
                 return (
                     <div
@@ -357,7 +357,7 @@ export class MobileInterface extends React.Component {
                 {this.renderPathbar()}
                 <div className={`sidebar ${this._sidebarActive ? "active" : ""}`}>
                     <div className="sidebarButtons">
-                        {this.scenes ?
+                        {this.dashboards ?
                             <>
                                 {buttons}
                                 <div
@@ -365,7 +365,7 @@ export class MobileInterface extends React.Component {
                                     onClick={this.returnMain}
                                     style={{ opacity: 0.7 }}>
                                     <FontAwesomeIcon className="right" icon="angle-double-left" size="lg" />
-                                    <div className="item-type">Return to scenes</div>
+                                    <div className="item-type">Return to dashboards</div>
                                 </div>
                             </> :
                             <>
@@ -373,9 +373,9 @@ export class MobileInterface extends React.Component {
                                 <div
                                     className="item"
                                     style={{ opacity: 0.7 }}
-                                    onClick={() => this.createNewScene()}>
+                                    onClick={() => this.createNewDashboard()}>
                                     <FontAwesomeIcon className="right" icon="plus" size="lg" />
-                                    <div className="item-type">Create New Scene</div>
+                                    <div className="item-type">Create New Dashboard</div>
                                 </div>
                             </>
                         }
@@ -388,27 +388,27 @@ export class MobileInterface extends React.Component {
     }
 
     /**
-     * Handles the 'Create New Scene' button in the menu (taken from MainView.tsx)
+     * Handles the 'Create New Dashboard' button in the menu (taken from MainView.tsx)
      */
     @action
-    createNewScene = async (id?: string) => {
-        const scens = Cast(Doc.UserDoc().myScenes, Doc) as Doc;
-        const sceneCount = DocListCast(scens.data).length + 1;
+    createNewDashboard = async (id?: string) => {
+        const scens = Cast(Doc.UserDoc().myDashboards, Doc) as Doc;
+        const dashboardCount = DocListCast(scens.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
-            title: "Collection " + sceneCount,
+            title: "Collection " + dashboardCount,
         };
         const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
-        const sceneDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Scene ${sceneCount}` }, id, "row");
+        const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Dashboard ${dashboardCount}` }, id, "row");
 
         const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
         const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
-        const cloneScene = ScriptField.MakeScript(`cloneScene()`);
-        sceneDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, cloneScene!]);
-        sceneDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "New Scene Layout"]);
+        const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`);
+        dashboardDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, cloneDashboard!]);
+        dashboardDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "New Dashboard Layout"]);
 
-        Doc.AddDocToList(scens, "data", sceneDoc);
+        Doc.AddDocToList(scens, "data", dashboardDoc);
     }
 
     // Button for switching between pen and ink mode
@@ -612,7 +612,7 @@ export class MobileInterface extends React.Component {
     }
 
     // Radial menu can only be used if it is a colleciton and it is not a homeDoc 
-    // (and cannot be used on Scene to avoid pin to presentation opening on right)
+    // (and cannot be used on Dashboard to avoid pin to presentation opening on right)
     @computed get displayRadialMenu() {
         return this._activeDoc.type === "collection" && this._activeDoc !== this._homeDoc &&
             this._activeDoc._viewType !== CollectionViewType.Docking ? <RadialMenu /> : (null);
@@ -657,7 +657,7 @@ export class MobileInterface extends React.Component {
                         {this.drawInk}
                         {this.uploadImageButton}
                     </div>
-                    {this.displayScenes}
+                    {this.displayDashboards}
                     {this.renderDefaultContent}
                 </GestureOverlay>
                 {this.displayRadialMenu}
@@ -669,7 +669,7 @@ export class MobileInterface extends React.Component {
 
 //Global functions for mobile menu
 Scripting.addGlobal(function switchToMobileLibrary() { return MobileInterface.Instance.switchToLibrary(); },
-    "opens the library to navigate through scenes on Dash Mobile");
+    "opens the library to navigate through dashboards on Dash Mobile");
 Scripting.addGlobal(function openMobileUploads() { return MobileInterface.Instance.toggleUpload(); },
     "opens the upload files menu for Dash Mobile");
 Scripting.addGlobal(function switchToMobileUploadCollection() { return MobileInterface.Instance.switchToMobileUploads(); },
-- 
cgit v1.2.3-70-g09d2


From 6048484932b9abe2962712bf2b8af56eeaab1176 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 22 Aug 2020 21:08:56 -0400
Subject: changed customTitle to title-custom

---
 src/client/views/DocumentDecorations.tsx                  | 6 +++---
 src/client/views/collections/CollectionSchemaHeaders.tsx  | 2 +-
 src/client/views/nodes/formattedText/FormattedTextBox.tsx | 4 ++--
 src/client/views/nodes/formattedText/RichTextRules.ts     | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c44c2968c..8e44bcf8f 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -117,7 +117,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 this._titleControlString = this._accumulatedTitle;
             } else if (this._titleControlString.startsWith("#")) {
                 const selectionTitleFieldKey = this._titleControlString.substring(1);
-                selectionTitleFieldKey === "title" && (SelectionManager.SelectedDocuments()[0].props.Document.customTitle = !this._accumulatedTitle.startsWith("-"));
+                selectionTitleFieldKey === "title" && (SelectionManager.SelectedDocuments()[0].dataDoc["title-custom"] = !this._accumulatedTitle.startsWith("-"));
                 UndoManager.RunInBatch(() => selectionTitleFieldKey && SelectionManager.SelectedDocuments().forEach(d => {
                     const value = typeof d.props.Document[selectionTitleFieldKey] === "number" ? +this._accumulatedTitle : this._accumulatedTitle;
                     Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, value, true);
@@ -624,8 +624,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     onBlur={e => this.titleBlur(true)} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} />
                 {minimal ? (null) : <div className="publishBox" // title="make document referenceable by its title"
                 // onPointerDown={action(e => {
-                //     if (!seldoc.props.Document.customTitle) {
-                //         seldoc.props.Document.customTitle = true;
+                //     if (!seldoc.props.Document["title-custom"]) {
+                //         seldoc.props.Document["title-custom"] = true;
                 //         StrCast(Doc.GetProto(seldoc.props.Document).title).startsWith("-") && (Doc.GetProto(seldoc.props.Document).title = StrCast(seldoc.props.Document.title).substring(1));
                 //         this._accumulatedTitle = StrCast(seldoc.props.Document.title);
                 //     }
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index a90d78a87..03a213002 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -302,7 +302,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
                 Doc.setDocFilter(this.props.Document, this._key, this.tempfilter, undefined);
                 this.updateFilter();
                 let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-                const blockedkeys = ["system", "customTitle", "limitHeight", "proto", "x", "y", "zIndex", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "layout", "layout_keyValue", "links"];
+                const blockedkeys = ["system", "title-custom", "limitHeight", "proto", "x", "y", "zIndex", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "layout", "layout_keyValue", "links"];
                 keyOptions = keyOptions.filter(n => !blockedkeys.includes(n) && !n.startsWith("_") && !n.startsWith("ACL"));
                 if (keyOptions.length) {
                     this.onSelect(keyOptions[0]);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ba0ac6293..7a6d263f9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -350,7 +350,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     updateTitle = () => {
         if ((this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing
-            StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.rootDoc.customTitle) {
+            StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.dataDoc["title-custom"]) {
             let node = this._editorView.state.doc;
             while (node.firstChild && node.firstChild.type.name !== "text") node = node.firstChild;
             const str = node.textContent;
@@ -1029,7 +1029,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 }
             }, 0);
             dataDoc.title = exportState.title;
-            this.rootDoc.customTitle = true;
+            this.dataDoc["title-custom"] = true;
             dataDoc.unchanged = true;
         } else {
             delete dataDoc[GoogleRef];
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index dc1d8a2c8..a455516a3 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -92,7 +92,7 @@ export class RichTextRules {
                     const inlineLayoutKey = "layout_" + inlineFieldKey; // the field holding the layout string that will render the inline annotation
                     const textDocInline = Docs.Create.TextDocument("", { layoutKey: inlineLayoutKey, _width: 75, _height: 35, annotationOn: textDoc, _autoHeight: true, _fontSize: "9pt", title: "inline comment" });
                     textDocInline.title = inlineFieldKey; // give the annotation its own title
-                    textDocInline.customTitle = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc
+                    textDocInline["title-custom"] = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc
                     textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point
                     textDocInline.proto = textDoc;  // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]]
                     textDocInline._textContext = ComputedField.MakeFunction(`copyField(self.${inlineFieldKey})`);
-- 
cgit v1.2.3-70-g09d2

