From af8df1fc1af11318cadf1b71373bef776461a5cc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 6 Apr 2022 10:42:36 -0400
Subject: uses linkMenu in propertiesWindow now.  updated linkMenu api, changed
 layout, made groups collapsible

---
 src/client/views/linking/LinkMenuGroup.tsx | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

(limited to 'src/client/views/linking/LinkMenuGroup.tsx')

diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 03377ad4e..5b1e29e67 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -1,4 +1,5 @@
 import { observer } from "mobx-react";
+import { observable, action } from "mobx";
 import { Doc, StrListCast } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
 import { Cast } from "../../../fields/Types";
@@ -14,6 +15,7 @@ interface LinkMenuGroupProps {
     groupType: string;
     showEditor: (linkDoc: Doc) => void;
     docView: DocumentView;
+    itemHandler?: (doc: Doc) => void;
 }
 
 @observer
@@ -36,6 +38,8 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
         return color;
     }
 
+    @observable _collapsed = false;
+
     render() {
         const set = new Set<Doc>(this.props.group);
         const groupItems = Array.from(set.keys()).map(linkDoc => {
@@ -43,6 +47,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
                 LinkManager.getOppositeAnchor(linkDoc, Cast(linkDoc.anchor2, Doc, null).annotationOn === this.props.sourceDoc ? Cast(linkDoc.anchor2, Doc, null) : Cast(linkDoc.anchor1, Doc, null));
             if (destination && this.props.sourceDoc) {
                 return <LinkMenuItem key={linkDoc[Id]}
+                    itemHandler={this.props.itemHandler}
                     groupType={this.props.groupType}
                     docView={this.props.docView}
                     linkDoc={linkDoc}
@@ -55,12 +60,12 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
 
         return (
             <div className="linkMenu-group" ref={this._menuRef}>
-                <div className="linkMenu-group-name" style={{ background: this.getBackgroundColor() }}>
+                <div className="linkMenu-group-name" onClick={action(() => this._collapsed = !this._collapsed)} style={{ background: this.getBackgroundColor() }}>
                     <p className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"}> {this.props.groupType}:</p>
                 </div>
-                <div className="linkMenu-group-wrapper">
+                {this._collapsed ? (null) : <div className="linkMenu-group-wrapper">
                     {groupItems}
-                </div>
+                </div>}
             </div >
         );
     }
-- 
cgit v1.2.3-70-g09d2


From 36261eac67ae6f872c9be2c9766d21ac24698f8e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 28 Apr 2022 01:37:27 -0400
Subject: fixed linkEditor to work when invoked from documentButtonsBar and
 properties sidebar is up.

---
 src/client/views/MainView.tsx                       |  2 +-
 src/client/views/PropertiesDocBacklinksSelector.tsx |  3 ++-
 src/client/views/linking/LinkMenu.tsx               | 20 ++++++++++++++------
 src/client/views/linking/LinkMenuGroup.tsx          |  2 ++
 src/client/views/linking/LinkMenuItem.tsx           |  6 +++---
 src/client/views/nodes/DocumentLinksButton.tsx      | 10 ++--------
 6 files changed, 24 insertions(+), 19 deletions(-)

(limited to 'src/client/views/linking/LinkMenuGroup.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index b73074899..c794c73db 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -632,7 +632,7 @@ export class MainView extends React.Component {
             <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
             {this.topbar}
             {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
-            {DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} /> : (null)}
+            {DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => DocumentLinksButton.LinkEditorDocView = undefined)} docView={DocumentLinksButton.LinkEditorDocView} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
             <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 2001 }} >
                 <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index dce3e35e8..4ead8eaf0 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -3,6 +3,7 @@ import { observer } from "mobx-react";
 import * as React from "react";
 import { Doc, DocListCast } from "../../fields/Doc";
 import { Cast } from "../../fields/Types";
+import { emptyFunction } from "../../Utils";
 import { DocumentType } from "../documents/DocumentTypes";
 import { LinkManager } from "../util/LinkManager";
 import { SelectionManager } from "../util/SelectionManager";
@@ -46,7 +47,7 @@ export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDo
     render() {
         return !SelectionManager.Views().length ? (null) : <div>
             {this.props.hideTitle ? (null) : <p key="contexts">Contexts:</p>}
-            <LinkMenu docView={SelectionManager.Views().lastElement()} itemHandler={this.getOnClick} position={{ x: 0 }} />
+            <LinkMenu docView={SelectionManager.Views().lastElement()} clearLinkEditor={emptyFunction} itemHandler={this.getOnClick} position={{ x: 0 }} />
         </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index bc922be36..a564c59d3 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -1,9 +1,10 @@
-import { action, computed, observable } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc } from "../../../fields/Doc";
 import { LinkManager } from "../../util/LinkManager";
+import { SelectionManager } from "../../util/SelectionManager";
 import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
-import { DocumentView, DocumentViewSharedProps } from "../nodes/DocumentView";
+import { DocumentView } from "../nodes/DocumentView";
 import { LinkDocPreview } from "../nodes/LinkDocPreview";
 import { LinkEditor } from "./LinkEditor";
 import './LinkMenu.scss';
@@ -14,6 +15,7 @@ interface Props {
     docView: DocumentView;
     position?: { x?: number, y?: number };
     itemHandler?: (doc: Doc) => void;
+    clearLinkEditor: () => void;
 }
 
 /**
@@ -21,7 +23,7 @@ interface Props {
  */
 @observer
 export class LinkMenu extends React.Component<Props> {
-    private _editorRef = React.createRef<HTMLDivElement>();
+    _editorRef = React.createRef<HTMLDivElement>();
     @observable _editingLink?: Doc;
     @observable _linkMenuRef = React.createRef<HTMLDivElement>();
 
@@ -29,16 +31,21 @@ export class LinkMenu extends React.Component<Props> {
         return this.props.position ?? (dv => ({ x: dv?.left || 0, y: (dv?.bottom || 0) + 15 }))(this.props.docView.getBounds());
     }
 
+    clear = action(() => {
+        this.props.clearLinkEditor();
+        this._editingLink = undefined;
+    });
+
     componentDidMount() { document.addEventListener("pointerdown", this.onPointerDown); }
     componentWillUnmount() { document.removeEventListener("pointerdown", this.onPointerDown); }
 
-    onPointerDown = (e: PointerEvent) => {
+    onPointerDown = action((e: PointerEvent) => {
         LinkDocPreview.Clear();
         if (!this._linkMenuRef.current?.contains(e.target as any) &&
             !this._editorRef.current?.contains(e.target as any)) {
-            DocumentLinksButton.ClearLinkEditor();
+            this.clear();
         }
-    }
+    });
 
     /**
      * maps each link to a JSX element to be rendered
@@ -54,6 +61,7 @@ export class LinkMenu extends React.Component<Props> {
                 sourceDoc={this.props.docView.props.Document}
                 group={group[1]}
                 groupType={group[0]}
+                clearLinkEditor={this.clear}
                 showEditor={action(linkDoc => this._editingLink = linkDoc)} />);
 
         return linkItems.length ? linkItems : this.props.position ? [<></>] : [<p key="">No links have been created yet. Drag the linking button onto another document to create a link.</p>];
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 5b1e29e67..fa6a2f506 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -13,6 +13,7 @@ interface LinkMenuGroupProps {
     sourceDoc: Doc;
     group: Doc[];
     groupType: string;
+    clearLinkEditor: () => void;
     showEditor: (linkDoc: Doc) => void;
     docView: DocumentView;
     itemHandler?: (doc: Doc) => void;
@@ -53,6 +54,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
                     linkDoc={linkDoc}
                     sourceDoc={this.props.sourceDoc}
                     destinationDoc={destination}
+                    clearLinkEditor={this.props.clearLinkEditor}
                     showEditor={this.props.showEditor}
                     menuRef={this._menuRef} />;
             }
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d6400a6b3..3ddcf803d 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -13,7 +13,6 @@ import { DragManager } from '../../util/DragManager';
 import { Hypothesis } from '../../util/HypothesisUtils';
 import { LinkManager } from '../../util/LinkManager';
 import { undoBatch } from '../../util/UndoManager';
-import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { DocumentView } from '../nodes/DocumentView';
 import { LinkDocPreview } from '../nodes/LinkDocPreview';
 import './LinkMenuItem.scss';
@@ -26,6 +25,7 @@ interface LinkMenuItemProps {
     docView: DocumentView;
     sourceDoc: Doc;
     destinationDoc: Doc;
+    clearLinkEditor: () => void;
     showEditor: (linkDoc: Doc) => void;
     menuRef: React.Ref<HTMLDivElement>;
     itemHandler?: (doc: Doc) => void;
@@ -92,12 +92,12 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                 const eleClone: any = this._drag.current!.cloneNode(true);
                 eleClone.style.transform = `translate(${e.x}px, ${e.y}px)`;
                 StartLinkTargetsDrag(eleClone, this.props.docView, e.x, e.y, this.props.sourceDoc, [this.props.linkDoc]);
-                DocumentLinksButton.ClearLinkEditor();
+                this.props.clearLinkEditor();
                 return true;
             },
             emptyFunction,
             () => {
-                DocumentLinksButton.ClearLinkEditor();
+                this.props.clearLinkEditor();
                 if (this.props.itemHandler) {
 
                     this.props.itemHandler?.(this.props.linkDoc);
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 46537df7e..9b79db319 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -1,21 +1,17 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Tooltip } from "@material-ui/core";
-import { action, computed, observable, runInAction, trace } from "mobx";
+import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, Opt } from "../../../fields/Doc";
-import { Id } from "../../../fields/FieldSymbols";
-import { ScriptField } from "../../../fields/ScriptField";
 import { StrCast } from "../../../fields/Types";
 import { TraceMobx } from "../../../fields/util";
 import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils";
-import { DocServer } from "../../DocServer";
-import { Docs, DocUtils } from "../../documents/Documents";
+import { DocUtils } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
 import { Hypothesis } from "../../util/HypothesisUtils";
 import { LinkManager } from "../../util/LinkManager";
 import { undoBatch, UndoManager } from "../../util/UndoManager";
 import { Colors } from "../global/globalEnums";
-import { LightboxView } from "../LightboxView";
 import './DocumentLinksButton.scss';
 import { DocumentView } from "./DocumentView";
 import { LinkDescriptionPopup } from "./LinkDescriptionPopup";
@@ -46,8 +42,6 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
     @observable public static invisibleWebDoc: Opt<Doc>;
     public static invisibleWebRef = React.createRef<HTMLDivElement>();
 
-    @action public static ClearLinkEditor() { DocumentLinksButton.LinkEditorDocView = undefined; }
-
     @action @undoBatch
     onLinkButtonMoved = (e: PointerEvent) => {
         if (this.props.InMenu && this.props.StartLink) {
-- 
cgit v1.2.3-70-g09d2

