From 2a313f28fcb8675223708b0657de7517a3281095 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 17 Apr 2024 12:27:21 -0400
Subject: restoring eslint - updates not complete yet

---
 .../views/collections/CollectionDockingView.tsx    | 156 ++++++++++++---------
 1 file changed, 89 insertions(+), 67 deletions(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index b2897a9b7..9a1781b93 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -2,25 +2,26 @@ import { action, IReactionDisposer, makeObservable, observable, reaction } from
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
-import * as GoldenLayout from '../../../client/goldenLayout';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, incrementTitleCopy } from '../../../ClientUtils';
 import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
 import { AclAdmin, AclEdit, DocData } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
-import { FieldValue, ImageCast, NumCast, StrCast } from '../../../fields/Types';
+import { ImageCast, NumCast, StrCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
 import { GetEffectiveAcl, inheritParentAcls, SetPropSetterCb } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, emptyFunction, incrementTitleCopy } from '../../../Utils';
+import { emptyFunction } from '../../../Utils';
 import { DocServer } from '../../DocServer';
 import { Docs } from '../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import * as GoldenLayout from '../../goldenLayout';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager } from '../../util/DragManager';
 import { InteractionUtils } from '../../util/InteractionUtils';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SelectionManager } from '../../util/SelectionManager';
-import { SettingsManager } from '../../util/SettingsManager';
+import { SnappingManager } from '../../util/SnappingManager';
 import { undoable, undoBatch, UndoManager } from '../../util/UndoManager';
 import { DashboardView } from '../DashboardView';
 import { LightboxView } from '../LightboxView';
@@ -32,11 +33,12 @@ import './CollectionDockingView.scss';
 import { CollectionFreeFormView } from './collectionFreeForm';
 import { CollectionSubView } from './CollectionSubView';
 import { TabDocView } from './TabDocView';
-import { ComputedField } from '../../../fields/ScriptField';
+
 const _global = (window /* browser */ || global) /* node */ as any;
 
 @observer
 export class CollectionDockingView extends CollectionSubView() {
+    // eslint-disable-next-line no-use-before-define
     @observable public static Instance: CollectionDockingView | undefined = undefined;
     public static makeDocumentConfig(document: Doc, panelName?: string, width?: number, keyValue?: boolean) {
         return {
@@ -68,7 +70,7 @@ export class CollectionDockingView extends CollectionSubView() {
         super(props);
         makeObservable(this);
         if (this._props.renderDepth < 0) CollectionDockingView.Instance = this;
-        //Why is this here?
+        // Why is this here?
         (window as any).React = React;
         (window as any).ReactDOM = ReactDOM;
         DragManager.StartWindowDrag = this.StartOtherDrag;
@@ -201,6 +203,7 @@ export class CollectionDockingView extends CollectionSubView() {
             } else if (instance._goldenLayout.root.contentItems[0].isRow) {
                 // if row
                 switch (pullSide) {
+                    // eslint-disable-next-line default-case-last
                     default:
                     case OpenWhereMod.none:
                     case OpenWhereMod.right:
@@ -210,7 +213,7 @@ export class CollectionDockingView extends CollectionSubView() {
                         glayRoot.contentItems[0].addChild(newContentItem(), 0);
                         break;
                     case OpenWhereMod.top:
-                    case OpenWhereMod.bottom:
+                    case OpenWhereMod.bottom: {
                         // if not going in a row layout, must add already existing content into column
                         const rowlayout = glayRoot.contentItems[0];
                         const newColumn = rowlayout.layoutManager.createContentItem({ type: 'column' }, instance._goldenLayout);
@@ -229,6 +232,7 @@ export class CollectionDockingView extends CollectionSubView() {
 
                         rowlayout.config.height = 50;
                         newItem.config.height = 50;
+                    }
                 }
             } else {
                 // if (instance._goldenLayout.root.contentItems[0].isColumn) { // if column
@@ -241,7 +245,7 @@ export class CollectionDockingView extends CollectionSubView() {
                         break;
                     case 'left':
                     case 'right':
-                    default:
+                    default: {
                         // if not going in a row layout, must add already existing content into column
                         const collayout = glayRoot.contentItems[0];
                         const newRow = collayout.layoutManager.createContentItem({ type: 'row' }, instance._goldenLayout);
@@ -260,6 +264,7 @@ export class CollectionDockingView extends CollectionSubView() {
 
                         collayout.config.width = 50;
                         newItem.config.width = 50;
+                    }
                 }
             }
             instance._ignoreStateChange = JSON.stringify(instance._goldenLayout.toConfig());
@@ -278,10 +283,10 @@ export class CollectionDockingView extends CollectionSubView() {
     }
     setupGoldenLayout = async () => {
         if (this._unmounting) return;
-        //const config = StrCast(this.Document.dockingConfig, JSON.stringify(DashboardView.resetDashboard(this.Document)));
+        // const config = StrCast(this.Document.dockingConfig, JSON.stringify(DashboardView.resetDashboard(this.Document)));
         const config = StrCast(this.Document.dockingConfig);
         if (config) {
-            const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+            const matches = config.match(/"documentId":"[a-z0-9-]+"/g);
             const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? [];
 
             await Promise.all(docids.map(id => DocServer.GetRefField(id)));
@@ -289,12 +294,13 @@ export class CollectionDockingView extends CollectionSubView() {
             if (this._goldenLayout) {
                 if (config === JSON.stringify(this._goldenLayout.toConfig())) {
                     return;
-                } else {
-                    try {
-                        this._goldenLayout.unbind('tabCreated', this.tabCreated);
-                        this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
-                        this._goldenLayout.unbind('stackCreated', this.stackCreated);
-                    } catch (e) {}
+                }
+                try {
+                    this._goldenLayout.unbind('tabCreated', this.tabCreated);
+                    this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
+                    this._goldenLayout.unbind('stackCreated', this.stackCreated);
+                } catch (e) {
+                    /* empty */
                 }
                 this.tabMap.clear();
                 this._goldenLayout.destroy();
@@ -323,7 +329,7 @@ export class CollectionDockingView extends CollectionSubView() {
      */
     titleChanged = (target: any, value: any) => {
         const title = Field.toString(value);
-        if (title.startsWith('@') && !title.substring(1).match(/[\(\)\[\]@]/) && title.length > 1) {
+        if (title.startsWith('@') && !title.substring(1).match(/[()[\]@]/) && title.length > 1) {
             const embedding = DocListCast(target.proto_embeddings).lastElement();
             embedding && Doc.AddToMyPublished(embedding);
         } else if (!title.startsWith('@')) {
@@ -337,7 +343,7 @@ export class CollectionDockingView extends CollectionSubView() {
         if (this._containerRef.current) {
             this._lightboxReactionDisposer = reaction(
                 () => LightboxView.LightboxDoc,
-                doc => setTimeout(() => !doc && this.onResize(undefined))
+                doc => setTimeout(() => !doc && this.onResize())
             );
             new _global.ResizeObserver(this.onResize).observe(this._containerRef.current);
             this._reactionDisposer = reaction(
@@ -356,12 +362,12 @@ export class CollectionDockingView extends CollectionSubView() {
                 { fireImmediately: true }
             );
             reaction(
-                () => [SettingsManager.userBackgroundColor, SettingsManager.userBackgroundColor],
+                () => [SnappingManager.userBackgroundColor, SnappingManager.userBackgroundColor],
                 () => {
                     clearStyleSheetRules(CollectionDockingView._highlightStyleSheet);
-                    addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { background: `${SettingsManager.userBackgroundColor} !important` });
-                    addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { color: `${SettingsManager.userColor} !important` });
-                    addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${SettingsManager.userBackgroundColor} !important` });
+                    addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { background: `${SnappingManager.userBackgroundColor} !important` });
+                    addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { color: `${SnappingManager.userColor} !important` });
+                    addStyleSheetRule(SnappingManager.SettingsStyle, 'lm_header', { background: `${SnappingManager.userBackgroundColor} !important` });
                 },
                 { fireImmediately: true }
             );
@@ -374,7 +380,9 @@ export class CollectionDockingView extends CollectionSubView() {
         try {
             this._goldenLayout.unbind('stackCreated', this.stackCreated);
             this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
-        } catch (e) {}
+        } catch (e) {
+            /* empty */
+        }
         this._goldenLayout?.destroy();
         window.removeEventListener('resize', this.onResize);
         window.removeEventListener('mouseup', this.onPointerUp);
@@ -384,7 +392,7 @@ export class CollectionDockingView extends CollectionSubView() {
     };
 
     @action
-    onResize = (event: any) => {
+    onResize = () => {
         const cur = this._containerRef.current;
         // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
         !LightboxView.LightboxDoc && cur && this._goldenLayout?.updateSize(cur.getBoundingClientRect().width, cur.getBoundingClientRect().height);
@@ -392,7 +400,7 @@ export class CollectionDockingView extends CollectionSubView() {
 
     endUndoBatch = () => {
         const json = JSON.stringify(this._goldenLayout.toConfig());
-        const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+        const matches = json.match(/"documentId":"[a-z0-9-]+"/g);
         const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', ''));
         const docs = !docids
             ? []
@@ -415,7 +423,7 @@ export class CollectionDockingView extends CollectionSubView() {
     };
 
     @action
-    onPointerUp = (e: MouseEvent): void => {
+    onPointerUp = (): void => {
         window.removeEventListener('pointerup', this.onPointerUp);
         DragManager.CompleteWindowDrag = undefined;
         setTimeout(this.endUndoBatch, 100);
@@ -453,24 +461,27 @@ export class CollectionDockingView extends CollectionSubView() {
         if (content) {
             const _width = DivWidth(content);
             const _height = DivHeight(content);
-            return CollectionFreeFormView.UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', (iconFile, _nativeWidth, _nativeHeight) => {
+            return CollectionFreeFormView.UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', iconFile => {
                 const proto = this.dataDoc; // Cast(img.proto, Doc, null)!;
-                proto['thumb_nativeWidth'] = _width;
-                proto['thumb_nativeHeight'] = _height;
+                proto.thumb_nativeWidth = _width;
+                proto.thumb_nativeHeight = _height;
                 proto.thumb = new ImageField(iconFile);
             });
         }
+        return undefined;
     }
     public static async TakeSnapshot(doc: Doc | undefined, clone = false) {
         if (!doc) return undefined;
         let json = StrCast(doc.dockingConfig);
         if (clone) {
             const cloned = await Doc.MakeClone(doc);
-            Array.from(cloned.map.entries()).map(entry => (json = json.replace(entry[0], entry[1][Id])));
+            Array.from(cloned.map.entries()).forEach(entry => {
+                json = json.replace(entry[0], entry[1][Id]);
+            });
             cloned.clone[DocData].dockingConfig = json;
             return DashboardView.openDashboard(cloned.clone);
         }
-        const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+        const matches = json.match(/"documentId":"[a-z0-9-]+"/g);
         const origtabids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) || [];
         const origtabs = origtabids
             .map(id => DocServer.GetCachedRefField(id))
@@ -508,19 +519,20 @@ export class CollectionDockingView extends CollectionSubView() {
 
     tabDestroyed = (tab: any) => {
         this._flush = this._flush ?? UndoManager.StartBatch('tab movement');
-        if (tab.DashDoc && ![DocumentType.PRES].includes(tab.DashDoc?.type) && !tab.contentItem.config.props.keyValue) {
-            Doc.AddDocToList(Doc.MyHeaderBar, 'data', tab.DashDoc, undefined, undefined, true);
+        const dashDoc = tab.DashDoc;
+        if (dashDoc && ![DocumentType.PRES].includes(dashDoc.type) && !tab.contentItem.config.props.keyValue) {
+            Doc.AddDocToList(Doc.MyHeaderBar, 'data', dashDoc, undefined, undefined, true);
             // if you close a tab that is not embedded somewhere else (an embedded Doc can be opened simultaneously in a tab), then add the tab to recently closed
-            if (tab.DashDoc.embedContainer === this.Document) tab.DashDoc.embedContainer = undefined;
-            if (!tab.DashDoc.embedContainer) {
-                Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', tab.DashDoc, undefined, true, true);
-                Doc.RemoveEmbedding(tab.DashDoc, tab.DashDoc);
+            if (dashDoc.embedContainer === this.Document) dashDoc.embedContainer = undefined;
+            if (!dashDoc.embedContainer) {
+                Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', dashDoc, undefined, true, true);
+                Doc.RemoveEmbedding(dashDoc, dashDoc);
             }
         }
         if (CollectionDockingView.Instance) {
             const dview = CollectionDockingView.Instance.Document;
-            const fieldKey = CollectionDockingView.Instance.props.fieldKey;
-            Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc);
+            const { fieldKey } = CollectionDockingView.Instance.props;
+            Doc.RemoveDocFromList(dview, fieldKey, dashDoc);
             this.tabMap.delete(tab);
             tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
             this.stateChanged();
@@ -531,8 +543,8 @@ export class CollectionDockingView extends CollectionSubView() {
         tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
     };
 
-    stackCreated = (stack: any) => {
-        stack = stack.header ? stack : stack.origin;
+    stackCreated = (stackIn: any) => {
+        const stack = stackIn.header ? stackIn : stackIn.origin;
         stack.header?.element.on('mousedown', (e: any) => {
             const dashboard = Doc.ActiveDashboard;
             if (dashboard && e.target === stack.header?.element[0] && e.button === 2) {
@@ -550,32 +562,29 @@ export class CollectionDockingView extends CollectionSubView() {
             }
         });
 
-        let addNewDoc = undoable(
-            action(() => {
-                const dashboard = Doc.ActiveDashboard;
-                if (dashboard) {
-                    dashboard.pane_count = NumCast(dashboard.pane_count) + 1;
-                    const docToAdd = Docs.Create.FreeformDocument([], {
-                        _width: this._props.PanelWidth(),
-                        _height: this._props.PanelHeight(),
-                        _layout_fitWidth: true,
-                        _freeform_backgroundGrid: true,
-                        title: `Untitled Tab ${NumCast(dashboard.pane_count)}`,
-                    });
-                    Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true);
-                    inheritParentAcls(this.dataDoc, docToAdd, false);
-                    CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
-                }
-            }),
-            'add new tab'
-        );
+        const addNewDoc = undoable(() => {
+            const dashboard = Doc.ActiveDashboard;
+            if (dashboard) {
+                dashboard.pane_count = NumCast(dashboard.pane_count) + 1;
+                const docToAdd = Docs.Create.FreeformDocument([], {
+                    _width: this._props.PanelWidth(),
+                    _height: this._props.PanelHeight(),
+                    _layout_fitWidth: true,
+                    _freeform_backgroundGrid: true,
+                    title: `Untitled Tab ${NumCast(dashboard.pane_count)}`,
+                });
+                Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true);
+                inheritParentAcls(this.dataDoc, docToAdd, false);
+                CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
+            }
+        }, 'add new tab');
 
         stack.header?.controlsContainer
-            .find('.lm_close') //get the close icon
-            .off('click') //unbind the current click handler
+            .find('.lm_close') // get the close icon
+            .off('click') // unbind the current click handler
             .click(
                 action(() => {
-                    //if (confirm('really close this?')) {
+                    // if (confirm('really close this?')) {
                     if ((!stack.parent.isRoot && !stack.parent.parent.isRoot) || stack.parent.contentItems.length > 1) {
                         const batch = UndoManager.StartBatch('close stack');
                         stack.remove();
@@ -595,11 +604,11 @@ export class CollectionDockingView extends CollectionSubView() {
             }
         });
         stack.header?.controlsContainer
-            .find('.lm_maximise') //get the close icon
+            .find('.lm_maximise') // get the close icon
             .click(() => setTimeout(this.stateChanged));
         stack.header?.controlsContainer
-            .find('.lm_popout') //get the popout icon
-            .off('click') //unbind the current click handler
+            .find('.lm_popout') // get the popout icon
+            .off('click') // unbind the current click handler
             .click(addNewDoc);
     };
 
@@ -609,13 +618,14 @@ export class CollectionDockingView extends CollectionSubView() {
             <div>
                 {href ? (
                     <img
+                        alt="thumbnail of nested dashboard"
                         style={{ background: 'white', top: 0, position: 'absolute' }}
                         src={href} // + '?d=' + (new Date()).getTime()}
                         width={this._props.PanelWidth()}
                         height={this._props.PanelHeight()}
                     />
                 ) : (
-                    <p>nested dashboards has no thumbnail</p>
+                    <p>nested dashboard has no thumbnail</p>
                 )}
             </div>
         ) : (
@@ -625,6 +635,7 @@ export class CollectionDockingView extends CollectionSubView() {
 }
 
 ScriptingGlobals.add(
+    // eslint-disable-next-line prefer-arrow-callback
     function openInLightbox(doc: any) {
         LightboxView.Instance.AddDocTab(doc, OpenWhere.lightbox);
     },
@@ -632,26 +643,37 @@ ScriptingGlobals.add(
     '(doc: any)'
 );
 ScriptingGlobals.add(
+    // eslint-disable-next-line prefer-arrow-callback
     function openDoc(doc: any, where: OpenWhere) {
         switch (where) {
             case OpenWhere.addRight:
                 return CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
             case OpenWhere.overlay:
+            default:
                 // prettier-ignore
                 switch (doc) {
                     case '<ScriptingRepl />': return OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: 'Scripting REPL' });
                     case "<UndoStack />": return OverlayView.Instance.addWindow(<UndoStack />, { x: 300, y: 100, width: 200, height: 200, title: 'Undo stack' });
+                    default: 
                 }
                 Doc.AddToMyOverlay(doc);
+                return true;
         }
     },
     'opens up document in location specified',
     '(doc: any)'
 );
 ScriptingGlobals.add(
+    // eslint-disable-next-line prefer-arrow-callback
     function openRepl() {
         return 'openRepl';
     },
     'opens up document in screen overlay layer',
     '(doc: any)'
 );
+// eslint-disable-next-line prefer-arrow-callback
+ScriptingGlobals.add(async function snapshotDashboard() {
+    const batch = UndoManager.StartBatch('snapshot');
+    await CollectionDockingView.TakeSnapshot(Doc.ActiveDashboard);
+    batch.end();
+}, 'creates a snapshot copy of a dashboard');
-- 
cgit v1.2.3-70-g09d2

