From 4ea0ea97359cf2f3e97367dafbfaf9157ecc987b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 23 Mar 2024 15:30:49 -0400
Subject: made backspace deleting a schema row undoable.  fixed calling chat on
 string fields

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

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

diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 4a0ca8fe5..5f4948808 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -238,7 +238,7 @@ export class CollectionSchemaView extends CollectionSubView() {
                     }
                     break;
                 case 'Backspace': {
-                    this.removeDocument(this._selectedDocs);
+                    undoable(() => this.removeDocument(this._selectedDocs), 'delete schema row');
                     break;
                 }
                 case 'Escape': {
-- 
cgit v1.2.3-70-g09d2


From ccbe6cafa422616ec4ffe5c2d1caed7597719007 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 30 Mar 2024 10:14:19 -0400
Subject: cleanup of import orderings.

---
 src/client/util/CaptureManager.tsx                 |   2 +-
 src/client/views/DocumentDecorations.tsx           |   3 +-
 src/client/views/GlobalKeyHandler.ts               |   8 +-
 src/client/views/LightboxView.tsx                  |   2 +-
 src/client/views/PropertiesView.tsx                |   3 +-
 src/client/views/collections/CollectionMenu.tsx    |  12 +-
 .../views/collections/CollectionNoteTakingView.tsx |   7 +-
 src/client/views/collections/TabDocView.tsx        |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   4 +-
 .../collectionSchema/CollectionSchemaView.tsx      |  14 +-
 .../views/newlightbox/Header/LightboxHeader.tsx    | 108 ++++----
 .../RecommendationList/RecommendationList.tsx      | 295 +++++++++++----------
 src/client/views/nodes/DocumentView.tsx            |   3 +-
 src/client/views/nodes/EquationBox.tsx             |   2 +-
 src/client/views/nodes/LinkBox.tsx                 |   2 +-
 src/client/views/nodes/WebBox.tsx                  |   4 +-
 src/client/views/nodes/trails/PresBox.tsx          |   4 +-
 src/client/views/topbar/TopBar.tsx                 |   6 +-
 18 files changed, 253 insertions(+), 228 deletions(-)

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

diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 2e13aff2f..8451357ef 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -2,9 +2,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { addStyleSheet } from '../../Utils';
 import { Doc } from '../../fields/Doc';
 import { DocCast, StrCast } from '../../fields/Types';
-import { addStyleSheet } from '../../Utils';
 import { LightboxView } from '../views/LightboxView';
 import { MainViewModal } from '../views/MainViewModal';
 import './CaptureManager.scss';
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4d9b93896..6698cd5bc 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -10,7 +10,6 @@ import { DateField } from '../../fields/DateField';
 import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
 import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols';
 import { InkField } from '../../fields/InkField';
-import { RichTextField } from '../../fields/RichTextField';
 import { ScriptField } from '../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
 import { GetEffectiveAcl } from '../../fields/util';
@@ -33,8 +32,8 @@ import { CollectionFreeFormView } from './collections/collectionFreeForm';
 import { Colors } from './global/globalEnums';
 import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
 import { ImageBox } from './nodes/ImageBox';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { KeyValueBox } from './nodes/KeyValueBox';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 
 interface DocumentDecorationsProps {
     PanelWidth: number;
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 667d8dbb0..2f64ea28c 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -13,18 +13,18 @@ import { SettingsManager } from '../util/SettingsManager';
 import { SharingManager } from '../util/SharingManager';
 import { SnappingManager } from '../util/SnappingManager';
 import { UndoManager } from '../util/UndoManager';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
-import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
 import { ContextMenu } from './ContextMenu';
 import { DocumentDecorations } from './DocumentDecorations';
 import { InkStrokeProperties } from './InkStrokeProperties';
 import { LightboxView } from './LightboxView';
 import { MainView } from './MainView';
+import { CollectionDockingView } from './collections/CollectionDockingView';
+import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
 import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { OpenWhereMod } from './nodes/DocumentView';
-import { AnchorMenu } from './pdf/AnchorMenu';
 import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { AnchorMenu } from './pdf/AnchorMenu';
 
 const modifiers = ['control', 'meta', 'shift', 'alt'];
 type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo;
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 3d77ee901..ef4b5b4ca 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -19,9 +19,9 @@ import { Transform } from '../util/Transform';
 import { GestureOverlay } from './GestureOverlay';
 import './LightboxView.scss';
 import { ObservableReactComponent } from './ObservableReactComponent';
+import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
-import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
 import { TabDocView } from './collections/TabDocView';
 import { DocumentView, OpenWhere, OpenWhereMod } from './nodes/DocumentView';
 
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index dc814bb16..ae29382c1 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -10,7 +10,7 @@ import * as React from 'react';
 import { ColorResult, SketchPicker } from 'react-color';
 import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs"
 import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
-import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
+import { Doc, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
 import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols';
 import { Id } from '../../fields/FieldSymbols';
 import { InkField } from '../../fields/InkField';
@@ -41,7 +41,6 @@ import { DocumentView, OpenWhere } from './nodes/DocumentView';
 import { StyleProviderFuncType } from './nodes/FieldView';
 import { KeyValueBox } from './nodes/KeyValueBox';
 import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
-import { LinkBox } from './nodes/LinkBox';
 const _global = (window /* browser */ || global) /* node */ as any;
 
 interface PropertiesViewProps {
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 8729ef549..4f25f69ef 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,15 +1,16 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, Lambda, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { Lambda, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
 import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
 import { RichTextField } from '../../../fields/RichTextField';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
 import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
 import { DragManager, dropActionType } from '../../util/DragManager';
 import { SelectionManager } from '../../util/SelectionManager';
@@ -19,11 +20,10 @@ import { undoBatch } from '../../util/UndoManager';
 import { AntimodeMenu } from '../AntimodeMenu';
 import { EditableView } from '../EditableView';
 import { MainView } from '../MainView';
-import { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
 import { DefaultStyleProvider } from '../StyleProvider';
-import { CollectionLinearView } from './collectionLinear';
+import { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
 import './CollectionMenu.scss';
-import { DocData } from '../../../fields/DocSymbols';
+import { CollectionLinearView } from './collectionLinear';
 
 interface CollectionMenuProps {
     panelHeight: () => number;
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 6318620e0..5b91216cb 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,4 +1,4 @@
-import { action, computed, IReactionDisposer, makeObservable, observable, observe, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, Field, Opt } from '../../../fields/Doc';
@@ -9,7 +9,7 @@ import { listSpec } from '../../../fields/Schema';
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
-import { DivHeight, emptyFunction, returnFalse, returnZero, smoothScroll, Utils } from '../../../Utils';
+import { DivHeight, emptyFunction, returnZero, smoothScroll, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DragManager, dropActionType } from '../../util/DragManager';
 import { SnappingManager } from '../../util/SnappingManager';
@@ -19,14 +19,13 @@ import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { LightboxView } from '../LightboxView';
 import { DocumentView } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { StyleProp } from '../StyleProvider';
 import './CollectionNoteTakingView.scss';
 import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
 import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
 import { CollectionSubView } from './CollectionSubView';
-import { JsxElement } from 'typescript';
 const _global = (window /* browser */ || global) /* node */ as any;
 
 /**
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 699ec3b95..3ff58c326 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -30,7 +30,7 @@ import { ObservableReactComponent } from '../ObservableReactComponent';
 import { DefaultStyleProvider, StyleProp } from '../StyleProvider';
 import { Colors } from '../global/globalEnums';
 import { DocumentView, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView';
 import { KeyValueBox } from '../nodes/KeyValueBox';
 import { DashFieldView } from '../nodes/formattedText/DashFieldView';
 import { PinProps, PresBox, PresMovement } from '../nodes/trails';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1b562939b..d435173f3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,6 @@
 import { Bezier } from 'bezier-js';
 import { Colors } from 'browndash-components';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { computedFn } from 'mobx-utils';
 import * as React from 'react';
@@ -17,7 +17,7 @@ import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../
 import { ImageField } from '../../../../fields/URLField';
 import { TraceMobx } from '../../../../fields/util';
 import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
-import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, numberValue, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
 import { CognitiveServices } from '../../../cognitive_services/CognitiveServices';
 import { Docs, DocUtils } from '../../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 5f4948808..df023b00f 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -1,33 +1,33 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Popup, PopupTrigger, Type } from 'browndash-components';
-import { action, computed, makeObservable, observable, ObservableMap, observe } from 'mobx';
+import { ObservableMap, action, computed, makeObservable, observable, observe } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
 import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
+import { DocData } from '../../../../fields/DocSymbols';
 import { Id } from '../../../../fields/FieldSymbols';
 import { List } from '../../../../fields/List';
 import { listSpec } from '../../../../fields/Schema';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
-import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Documents';
+import { DocUtils, Docs, DocumentOptions, FInfo } from '../../../documents/Documents';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { DragManager, dropActionType } from '../../../util/DragManager';
 import { SelectionManager } from '../../../util/SelectionManager';
 import { SettingsManager } from '../../../util/SettingsManager';
-import { undoable, undoBatch } from '../../../util/UndoManager';
+import { undoBatch, undoable } from '../../../util/UndoManager';
 import { ContextMenu } from '../../ContextMenu';
 import { EditableView } from '../../EditableView';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
 import { Colors } from '../../global/globalEnums';
 import { DocumentView } from '../../nodes/DocumentView';
 import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
 import { KeyValueBox } from '../../nodes/KeyValueBox';
-import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
 import { CollectionSubView } from '../CollectionSubView';
 import './CollectionSchemaView.scss';
 import { SchemaColumnHeader } from './SchemaColumnHeader';
 import { SchemaRowBox } from './SchemaRowBox';
-import { DocData } from '../../../../fields/DocSymbols';
 const { default: { SCHEMA_NEW_NODE_HEIGHT } } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
 
 export enum ColumnType {
diff --git a/src/client/views/newlightbox/Header/LightboxHeader.tsx b/src/client/views/newlightbox/Header/LightboxHeader.tsx
index a272ce294..76efe0185 100644
--- a/src/client/views/newlightbox/Header/LightboxHeader.tsx
+++ b/src/client/views/newlightbox/Header/LightboxHeader.tsx
@@ -1,62 +1,70 @@
-import './LightboxHeader.scss';
-import * as React from 'react';
-import { INewLightboxHeader } from "./utils";
-import { NewLightboxView } from '../NewLightboxView';
-import { StrCast } from '../../../../fields/Types';
-import { EditableText } from '../components/EditableText';
-import { getType } from '../utils';
 import { Button, IconButton, Size, Type } from 'browndash-components';
-import { MdExplore, MdTravelExplore } from 'react-icons/md'
-import { BsBookmark, BsBookmarkFill } from 'react-icons/bs'
+import * as React from 'react';
+import { BsBookmark, BsBookmarkFill } from 'react-icons/bs';
+import { MdTravelExplore } from 'react-icons/md';
 import { Doc } from '../../../../fields/Doc';
+import { StrCast } from '../../../../fields/Types';
 import { LightboxView } from '../../LightboxView';
 import { Colors } from '../../global/globalEnums';
-
+import { NewLightboxView } from '../NewLightboxView';
+import { EditableText } from '../components/EditableText';
+import { getType } from '../utils';
+import './LightboxHeader.scss';
+import { INewLightboxHeader } from './utils';
 
 export const NewLightboxHeader = (props: INewLightboxHeader) => {
-    const {height = 100, width} = props;
-    const [doc, setDoc] = React.useState<Doc | undefined>(LightboxView.LightboxDoc)
-    const [editing, setEditing] = React.useState<boolean>(false)
-    const [title, setTitle] = React.useState<JSX.Element | null>(
-        (null)
-    )
+    const { height = 100, width } = props;
+    const [doc, setDoc] = React.useState<Doc | undefined>(LightboxView.LightboxDoc);
+    const [editing, setEditing] = React.useState<boolean>(false);
+    const [title, setTitle] = React.useState<JSX.Element | null>(null);
     React.useEffect(() => {
-        let lbDoc = LightboxView.LightboxDoc
-        setDoc(lbDoc)
+        let lbDoc = LightboxView.LightboxDoc;
+        setDoc(lbDoc);
         if (lbDoc) {
             setTitle(
-                <EditableText 
-                editing={editing}
-                text={StrCast(lbDoc.title)} 
-                onEdit={(newText: string) => {
-                    if(lbDoc) lbDoc.title = newText;
-                }} 
-                setEditing={setEditing}            
-            />)
+                <EditableText
+                    editing={editing}
+                    text={StrCast(lbDoc.title)}
+                    onEdit={(newText: string) => {
+                        if (lbDoc) lbDoc.title = newText;
+                    }}
+                    setEditing={setEditing}
+                />
+            );
         }
-    }, [LightboxView.LightboxDoc])
+    }, [LightboxView.LightboxDoc]);
 
-    const [saved, setSaved] = React.useState<boolean>(false)
+    const [saved, setSaved] = React.useState<boolean>(false);
 
-    if (!doc) return null
-    else return <div className={`newLightboxHeader-container`} onPointerDown={(e) => e.stopPropagation()} style={{ minHeight: height, height: height, width: width }}>
-        <div className={`title-container`}>
-            <div className={`lb-label`}>Title</div>
-            {title}
-        </div>
-        <div className={`type-container`}>
-            <div className={`lb-label`}>Type</div>
-            <div className={`type`}>{getType(StrCast(doc.type))}</div>
-        </div>
-        <div style={{gridColumn: 2, gridRow: 1, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}>
-            <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill/> : <BsBookmark/>}/>
-            <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill/> : <BsBookmark/>}/>
-        </div>
-        <div  style={{gridColumn: 2, gridRow: 2, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}>
-            <Button onClick={() => {
-                console.log(NewLightboxView.ExploreMode)
-                NewLightboxView.SetExploreMode(!NewLightboxView.ExploreMode)
-            }} size={Size.XSMALL} color={Colors.DARK_GRAY} type={Type.SEC} text={"t-SNE 2D Embeddings"} icon={<MdTravelExplore/>}/>
-        </div>
-    </div>
-}
\ No newline at end of file
+    if (!doc) return null;
+    else
+        return (
+            <div className={`newLightboxHeader-container`} onPointerDown={e => e.stopPropagation()} style={{ minHeight: height, height: height, width: width }}>
+                <div className={`title-container`}>
+                    <div className={`lb-label`}>Title</div>
+                    {title}
+                </div>
+                <div className={`type-container`}>
+                    <div className={`lb-label`}>Type</div>
+                    <div className={`type`}>{getType(StrCast(doc.type))}</div>
+                </div>
+                <div style={{ gridColumn: 2, gridRow: 1, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
+                    <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill /> : <BsBookmark />} />
+                    <IconButton size={Size.XSMALL} onClick={() => setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? <BsBookmarkFill /> : <BsBookmark />} />
+                </div>
+                <div style={{ gridColumn: 2, gridRow: 2, height: '100%', display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
+                    <Button
+                        onClick={() => {
+                            console.log(NewLightboxView.ExploreMode);
+                            NewLightboxView.SetExploreMode(!NewLightboxView.ExploreMode);
+                        }}
+                        size={Size.XSMALL}
+                        color={Colors.DARK_GRAY}
+                        type={Type.SEC}
+                        text={'t-SNE 2D Embeddings'}
+                        icon={<MdTravelExplore />}
+                    />
+                </div>
+            </div>
+        );
+};
diff --git a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
index 9f3c32e4e..1d502b73f 100644
--- a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
+++ b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
@@ -1,74 +1,67 @@
-import { GrClose } from 'react-icons/gr';
-import { IRecommendation, Recommendation } from "../components";
-import './RecommendationList.scss';
+import { IconButton, Size, Type } from 'browndash-components';
 import * as React from 'react';
-import { IRecommendationList } from "./utils";
-import { NewLightboxView } from '../NewLightboxView';
-import { DocCast, StrCast } from '../../../../fields/Types';
 import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
-import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
-import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
-import { IBounds } from '../ExploreView/utils';
+import { GrClose } from 'react-icons/gr';
+import { DocListCast, StrListCast } from '../../../../fields/Doc';
 import { List } from '../../../../fields/List';
-import { Id } from '../../../../fields/FieldSymbols';
+import { StrCast } from '../../../../fields/Types';
 import { LightboxView } from '../../LightboxView';
-import { IconButton, Size, Type } from 'browndash-components';
 import { Colors } from '../../global/globalEnums';
+import { IBounds } from '../ExploreView/utils';
+import { NewLightboxView } from '../NewLightboxView';
+import { IRecommendation, Recommendation } from '../components';
+import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
+import './RecommendationList.scss';
+import { IRecommendationList } from './utils';
 
 export const RecommendationList = (props: IRecommendationList) => {
-    const {loading, keywords} = props
-    const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true)
-    const [showMore, setShowMore] = React.useState<boolean>(false)
-    const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([])
-    const [update, setUpdate] = React.useState<boolean>(true)
-    const initialRecs: IRecommendation[] = [
-        {loading: true},
-        {loading: true},
-        {loading: true},
-        {loading: true},
-        {loading: true}
-    ];
-    const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs)
+    const { loading, keywords } = props;
+    const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true);
+    const [showMore, setShowMore] = React.useState<boolean>(false);
+    const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([]);
+    const [update, setUpdate] = React.useState<boolean>(true);
+    const initialRecs: IRecommendation[] = [{ loading: true }, { loading: true }, { loading: true }, { loading: true }, { loading: true }];
+    const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs);
 
     React.useEffect(() => {
         const getKeywords = async () => {
-            let text = StrCast(LightboxView.LightboxDoc?.text)
-            console.log('[1] fetching keywords')
-            const response = await fetchKeywords(text, 5, true)
-            console.log('[2] response:', response)
+            let text = StrCast(LightboxView.LightboxDoc?.text);
+            console.log('[1] fetching keywords');
+            const response = await fetchKeywords(text, 5, true);
+            console.log('[2] response:', response);
             const kw = response.keywords;
             console.log(kw);
             NewLightboxView.SetKeywords(kw);
             if (LightboxView.LightboxDoc) {
-                console.log('setting keywords on doc')
+                console.log('setting keywords on doc');
                 LightboxView.LightboxDoc.keywords = new List<string>(kw);
                 setKeywordsLoc(NewLightboxView.Keywords);
             }
-            setLoadingKeywords(false)
-        }
-        let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords)
+            setLoadingKeywords(false);
+        };
+        let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords);
         if (!keywordsList || keywordsList.length < 2) {
-            setLoadingKeywords(true)
-            getKeywords()
-            setUpdate(!update)
+            setLoadingKeywords(true);
+            getKeywords();
+            setUpdate(!update);
         } else {
-            setKeywordsLoc(keywordsList)
-            setLoadingKeywords(false)
-            setUpdate(!update)
+            setKeywordsLoc(keywordsList);
+            setLoadingKeywords(false);
+            setUpdate(!update);
         }
-    }, [NewLightboxView.LightboxDoc])
+    }, [NewLightboxView.LightboxDoc]);
 
-    // terms: vannevar bush, information spaces, 
+    // terms: vannevar bush, information spaces,
     React.useEffect(() => {
         const getRecommendations = async () => {
-            console.log('fetching recommendations')
-            let query = 'undefined'
-            if (keywordsLoc) query = keywordsLoc.join(',')
-            let src = StrCast(NewLightboxView.LightboxDoc?.text)
-            let dashDocs:IDocRequest[] = [];
+            console.log('fetching recommendations');
+            let query = 'undefined';
+            if (keywordsLoc) query = keywordsLoc.join(',');
+            let src = StrCast(NewLightboxView.LightboxDoc?.text);
+            let dashDocs: IDocRequest[] = [];
             // get linked docs
-            let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links)
-            console.log("linked docs", linkedDocs)
+            let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links);
+            console.log('linked docs', linkedDocs);
             // get context docs (docs that are also in the collection)
             // let contextDocs: Doc[] = DocListCast(DocCast(LightboxView.LightboxDoc?.context).data)
             // let docId = LightboxView.LightboxDoc && LightboxView.LightboxDoc[Id]
@@ -83,114 +76,142 @@ export const RecommendationList = (props: IRecommendationList) => {
             //         })
             //     }
             // })
-            console.log("dash docs", dashDocs)
+            console.log('dash docs', dashDocs);
             if (query !== undefined) {
-                const response = await fetchRecommendations(src, query, [], true)
-                const num_recs = response.num_recommendations
-                const recs = response.recommendations
-                const keywords = response.keywords
+                const response = await fetchRecommendations(src, query, [], true);
+                const num_recs = response.num_recommendations;
+                const recs = response.recommendations;
+                const keywords = response.keywords;
                 const response_bounds: IBounds = {
-                  max_x: response.max_x,
-                  max_y: response.max_y,
-                  min_x: response.min_x,
-                  min_y: response.min_y
-                }
+                    max_x: response.max_x,
+                    max_y: response.max_y,
+                    min_x: response.min_x,
+                    min_y: response.min_y,
+                };
                 // if (NewLightboxView.NewLightboxDoc) {
                 //     NewLightboxView.NewLightboxDoc.keywords = new List<string>(keywords);
                 //     setKeywordsLoc(NewLightboxView.Keywords);
                 // }
                 // console.log(response_bounds)
-                NewLightboxView.SetBounds(response_bounds)
+                NewLightboxView.SetBounds(response_bounds);
                 const recommendations: IRecommendation[] = [];
                 for (const key in recs) {
-                    console.log(key)
+                    console.log(key);
                     const title = recs[key].title;
-                    const url = recs[key].url
-                    const type = recs[key].type
-                    const text = recs[key].text
-                    const transcript = recs[key].transcript
-                    const previewUrl = recs[key].previewUrl
-                    const embedding = recs[key].embedding
-                    const distance = recs[key].distance
-                    const source = recs[key].source
-                    const related_concepts = recs[key].related_concepts
-                    const docId = recs[key].doc_id
-                    related_concepts.length >= 1 && recommendations.push({
-                        title: title,
-                        data: url,
-                        type: type,
-                        text: text,
-                        transcript: transcript,
-                        previewUrl: previewUrl,
-                        embedding: embedding,
-                        distance: Math.round(distance * 100) / 100,
-                        source: source,
-                        related_concepts: related_concepts,
-                        docId: docId
-                    })
+                    const url = recs[key].url;
+                    const type = recs[key].type;
+                    const text = recs[key].text;
+                    const transcript = recs[key].transcript;
+                    const previewUrl = recs[key].previewUrl;
+                    const embedding = recs[key].embedding;
+                    const distance = recs[key].distance;
+                    const source = recs[key].source;
+                    const related_concepts = recs[key].related_concepts;
+                    const docId = recs[key].doc_id;
+                    related_concepts.length >= 1 &&
+                        recommendations.push({
+                            title: title,
+                            data: url,
+                            type: type,
+                            text: text,
+                            transcript: transcript,
+                            previewUrl: previewUrl,
+                            embedding: embedding,
+                            distance: Math.round(distance * 100) / 100,
+                            source: source,
+                            related_concepts: related_concepts,
+                            docId: docId,
+                        });
                 }
                 recommendations.sort((a, b) => {
                     if (a.distance && b.distance) {
-                        return a.distance - b.distance
-                    } else return 0
-                })
-                console.log("[rec]: ", recommendations)
-                NewLightboxView.SetRecs(recommendations)
-                setRecs(recommendations)
+                        return a.distance - b.distance;
+                    } else return 0;
+                });
+                console.log('[rec]: ', recommendations);
+                NewLightboxView.SetRecs(recommendations);
+                setRecs(recommendations);
             }
-        }
+        };
         getRecommendations();
-    }, [update])
-    
-    
+    }, [update]);
 
-    return <div className={`recommendationlist-container`} onPointerDown={(e) => {e.stopPropagation()}}>
-        <div className={`header`}>
-            <div className={`title`}>
-                Recommendations
-            </div>
-            {NewLightboxView.LightboxDoc && <div style={{fontSize: 10}}>
-                The recommendations are produced based on the text in the document <b><u>{StrCast(NewLightboxView.LightboxDoc.title)}</u></b>. The following keywords are used to fetch the recommendations.
-            </div>}
-            <div className={`lb-label`}>Keywords</div>
-            {loadingKeywords ? <div className={`keywords`}>
-                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
-                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
-                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
-                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
+    return (
+        <div
+            className={`recommendationlist-container`}
+            onPointerDown={e => {
+                e.stopPropagation();
+            }}>
+            <div className={`header`}>
+                <div className={`title`}>Recommendations</div>
+                {NewLightboxView.LightboxDoc && (
+                    <div style={{ fontSize: 10 }}>
+                        The recommendations are produced based on the text in the document{' '}
+                        <b>
+                            <u>{StrCast(NewLightboxView.LightboxDoc.title)}</u>
+                        </b>
+                        . The following keywords are used to fetch the recommendations.
                     </div>
-                :
-                <div className={`keywords`}>
-                {keywordsLoc && keywordsLoc.map((word, ind) => {
-                    return <div className={`keyword`}>
-                        {word}
-                        <IconButton type={Type.PRIM} size={Size.XSMALL} color={Colors.DARK_GRAY} icon={<GrClose/>} onClick={() => {
-                            let kw = keywordsLoc
-                            kw.splice(ind)
-                            NewLightboxView.SetKeywords(kw)
-                        }}/>
+                )}
+                <div className={`lb-label`}>Keywords</div>
+                {loadingKeywords ? (
+                    <div className={`keywords`}>
+                        <div className={`keyword ${loadingKeywords && 'loading'}`} />
+                        <div className={`keyword ${loadingKeywords && 'loading'}`} />
+                        <div className={`keyword ${loadingKeywords && 'loading'}`} />
+                        <div className={`keyword ${loadingKeywords && 'loading'}`} />
                     </div>
-                })}
-            </div>
-            }
-            {!showMore ?
-            <div className={`lb-caret`} onClick={() => {setShowMore(true)}}>
-                More <FaCaretDown/>
+                ) : (
+                    <div className={`keywords`}>
+                        {keywordsLoc &&
+                            keywordsLoc.map((word, ind) => {
+                                return (
+                                    <div className={`keyword`}>
+                                        {word}
+                                        <IconButton
+                                            type={Type.PRIM}
+                                            size={Size.XSMALL}
+                                            color={Colors.DARK_GRAY}
+                                            icon={<GrClose />}
+                                            onClick={() => {
+                                                let kw = keywordsLoc;
+                                                kw.splice(ind);
+                                                NewLightboxView.SetKeywords(kw);
+                                            }}
+                                        />
+                                    </div>
+                                );
+                            })}
+                    </div>
+                )}
+                {!showMore ? (
+                    <div
+                        className={`lb-caret`}
+                        onClick={() => {
+                            setShowMore(true);
+                        }}>
+                        More <FaCaretDown />
+                    </div>
+                ) : (
+                    <div className={`more`}>
+                        <div
+                            className={`lb-caret`}
+                            onClick={() => {
+                                setShowMore(false);
+                            }}>
+                            Less <FaCaretUp />
+                        </div>
+                        <div className={`lb-label`}>Type</div>
+                        <div className={`lb-label`}>Sources</div>
+                    </div>
+                )}
             </div>
-            :
-            <div className={`more`}>
-                <div className={`lb-caret`} onClick={() => {setShowMore(false)}}>
-                    Less <FaCaretUp/>
-                </div>
-                <div className={`lb-label`}>Type</div>
-                <div className={`lb-label`}>Sources</div>
+            <div className={`recommendations`}>
+                {recs &&
+                    recs.map((rec: IRecommendation) => {
+                        return <Recommendation {...rec} />;
+                    })}
             </div>
-            }
-        </div>
-        <div className={`recommendations`}>
-            {recs && recs.map((rec: IRecommendation) => {
-                return <Recommendation {...rec} />
-            })}
         </div>
-    </div>
-}
\ No newline at end of file
+    );
+};
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 58820a498..a04030a5f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { Howl } from 'howler';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction, trace } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal';
@@ -50,7 +50,6 @@ import { KeyValueBox } from './KeyValueBox';
 import { LinkAnchorBox } from './LinkAnchorBox';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { PresEffect, PresEffectDirection } from './trails';
-import { InkingStroke } from '../InkingStroke';
 interface Window {
     MediaRecorder: MediaRecorder;
 }
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index c43f89be1..a557cff4f 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -1,6 +1,7 @@
 import { action, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { DivHeight, DivWidth } from '../../../Utils';
 import { Id } from '../../../fields/FieldSymbols';
 import { NumCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
@@ -11,7 +12,6 @@ import { LightboxView } from '../LightboxView';
 import './EquationBox.scss';
 import { FieldView, FieldViewProps } from './FieldView';
 import EquationEditor from './formattedText/EquationEditor';
-import { DivHeight, DivWidth } from '../../../Utils';
 
 @observer
 export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 7ad250714..36bd037ca 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -15,9 +15,9 @@ import { EditableView } from '../EditableView';
 import { LightboxView } from '../LightboxView';
 import { StyleProp } from '../StyleProvider';
 import { ComparisonBox } from './ComparisonBox';
+import { DocumentView } from './DocumentView';
 import { FieldView, FieldViewProps } from './FieldView';
 import './LinkBox.scss';
-import { DocumentView } from './DocumentView';
 
 @observer
 export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f4d5eef05..434415b96 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { htmlToText } from 'html-to-text';
-import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as WebRequest from 'web-request';
@@ -34,7 +34,7 @@ import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
 import { SidebarAnnos } from '../SidebarAnnos';
 import { StyleProp } from '../StyleProvider';
 import { DocumentView, OpenWhere } from './DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
+import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
 import { LinkInfo } from './LinkDocPreview';
 import { PinProps, PresBox } from './trails';
 import './WebBox.scss';
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index ae6da8fb0..cd9fec839 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -18,6 +18,7 @@ import { DocServer } from '../../../DocServer';
 import { Docs } from '../../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
 import { DocumentManager } from '../../../util/DocumentManager';
+import { dropActionType } from '../../../util/DragManager';
 import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
 import { SelectionManager } from '../../../util/SelectionManager';
 import { SerializationHelper } from '../../../util/SerializationHelper';
@@ -32,11 +33,10 @@ import { ViewBoxBaseComponent } from '../../DocComponent';
 import { Colors } from '../../global/globalEnums';
 import { LightboxView } from '../../LightboxView';
 import { DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
+import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
 import { ScriptingBox } from '../ScriptingBox';
 import './PresBox.scss';
 import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
-import { dropActionType } from '../../../util/DragManager';
 export interface pinDataTypes {
     scrollable?: boolean;
     dataviz?: number[];
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index addad2bbc..eab33114e 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -3,6 +3,7 @@ import { Button, IconButton, isDark, Size, Type } from 'browndash-components';
 import { action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { Flip } from 'react-awesome-reveal';
 import { FaBug } from 'react-icons/fa';
 import { Doc, DocListCast } from '../../../fields/Doc';
 import { AclAdmin, DashVersion } from '../../../fields/DocSymbols';
@@ -11,6 +12,7 @@ import { GetEffectiveAcl } from '../../../fields/util';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
 import { CurrentUserUtils } from '../../util/CurrentUserUtils';
 import { DocumentManager } from '../../util/DocumentManager';
+import { dropActionType } from '../../util/DragManager';
 import { PingManager } from '../../util/PingManager';
 import { ReportManager } from '../../util/reportManager/ReportManager';
 import { ServerStats } from '../../util/ServerStats';
@@ -23,11 +25,9 @@ import { CollectionLinearView } from '../collections/collectionLinear';
 import { DashboardView } from '../DashboardView';
 import { Colors } from '../global/globalEnums';
 import { DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import { DefaultStyleProvider } from '../StyleProvider';
 import './TopBar.scss';
-import { dropActionType } from '../../util/DragManager';
-import { Flip } from 'react-awesome-reveal';
-import { ObservableReactComponent } from '../ObservableReactComponent';
 
 /**
  * ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user
-- 
cgit v1.2.3-70-g09d2

