From 0e8aef275346b4ba3bc1bb91fda17a335c307bf1 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 3 Aug 2021 13:09:48 -0400
Subject: fixed using viewSpecs when following links to set filters/viewType
 properly.

---
 .../collectionFreeForm/CollectionFreeFormView.tsx       | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 143d8e070..ecc93285e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -159,8 +159,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         this.layoutDoc._viewScale = vals.scale;
     }
     freeformData = (force?: boolean) => this.fitToContent || force ? this.fitToContentVals : undefined;
-    freeformDocFilters = () => this._focusFilters || this.docFilters();
-    freeformRangeDocFilters = () => this._focusRangeFilters || this.docRangeFilters();
+    freeformDocFilters = () => this._focusFilters;
+    freeformRangeDocFilters = () => this._focusRangeFilters;
     reverseNativeScaling = () => this.fitToContent ? true : false;
     panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document._panX);
     panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document._panY);
@@ -1197,14 +1197,21 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         if (preview) {
             this._focusFilters = StrListCast(Doc.GetProto(anchor).docFilters);
             this._focusRangeFilters = StrListCast(Doc.GetProto(anchor).docRangeFilters);
-        } else if (anchor.pivotField !== undefined) {
-            this.layoutDoc._docFilters = new List<string>(StrListCast(anchor.docFilters));
-            this.layoutDoc._docRangeFilters = new List<string>(StrListCast(anchor.docRangeFilters));
+        } else {
+            if (anchor.docFilters) {
+                this.layoutDoc._docFilters = new List<string>(StrListCast(anchor.docFilters));
+            }
+            if (anchor.docRangeFilters) {
+                this.layoutDoc._docRangeFilters = new List<string>(StrListCast(anchor.docRangeFilters));
+            }
         }
         return 0;
     }
 
     getAnchor = () => {
+        if (this.props.Document.annotationOn) {
+            return this.rootDoc;
+        }
         const anchor = Docs.Create.TextanchorDocument({ title: StrCast(this.layoutDoc._viewType), annotationOn: this.rootDoc });
         const proto = Doc.GetProto(anchor);
         proto[ViewSpecPrefix + "_viewType"] = this.layoutDoc._viewType;
-- 
cgit v1.2.3-70-g09d2


From 70f98c6d4d3e457a05e7c84260bf33580ee0166a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 4 Aug 2021 10:34:25 -0400
Subject: restructured filters again so that filter icons show whether a
 document has a filter or inherits one.  following a link with a view spec
 overrides only locally set filters (not inherited ones).

---
 src/client/views/.DS_Store                         | Bin 10244 -> 10244 bytes
 .../views/collections/CollectionSchemaView.tsx     |   4 +--
 .../views/collections/CollectionStackingView.tsx   |   4 +--
 src/client/views/collections/CollectionSubView.tsx |  29 ++++++++++++---------
 .../views/collections/CollectionTimeView.tsx       |  12 +++------
 src/client/views/collections/CollectionView.tsx    |  14 +++++++---
 src/client/views/collections/TabDocView.tsx        |   9 ++++---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   8 ++----
 .../CollectionMulticolumnView.tsx                  |   4 +--
 .../CollectionMultirowView.tsx                     |   4 +--
 .../collectionSchema/CollectionSchemaView.tsx      |   4 +--
 src/client/views/nodes/DocumentView.tsx            |   6 ++---
 12 files changed, 50 insertions(+), 48 deletions(-)

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

diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store
index 33e624ef4..e4ac87aad 100644
Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index e1e04915a..380f82813 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -413,8 +413,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                     isContentActive={returnTrue}
                     isDocumentActive={returnFalse}
                     ScreenToLocalTransform={this.getPreviewTransform}
-                    docFilters={this.docFilters}
-                    docRangeFilters={this.docRangeFilters}
+                    docFilters={this.childDocFilters}
+                    docRangeFilters={this.childDocRangeFilters}
                     searchFilterDocs={this.searchFilterDocs}
                     styleProvider={DefaultStyleProvider}
                     layerProvider={undefined}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7aa8dfd56..b9bc83d49 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -239,10 +239,10 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={stackedDocTransform}
             focus={this.focusDocument}
-            docFilters={this.docFilters}
+            docFilters={this.childDocFilters}
             hideDecorationTitle={this.props.childHideDecorationTitle?.()}
             hideTitle={this.props.childHideTitle?.()}
-            docRangeFilters={this.docRangeFilters}
+            docRangeFilters={this.childDocRangeFilters}
             searchFilterDocs={this.searchFilterDocs}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 3b143aeef..e5f266acf 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -8,7 +8,7 @@ import { ScriptField } from "../../../fields/ScriptField";
 import { WebField } from "../../../fields/URLField";
 import { Cast, ScriptCast, NumCast, StrCast } from "../../../fields/Types";
 import { GestureUtils } from "../../../pen-gestures/GestureUtils";
-import { Utils, returnFalse } from "../../../Utils";
+import { Utils, returnFalse, returnEmptyFilter } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Networking } from "../../Network";
 import { ImageUtils } from "../../util/Import & Export/ImageUtils";
@@ -22,6 +22,7 @@ import ReactLoading from 'react-loading';
 
 export interface SubCollectionViewProps extends CollectionViewProps {
     CollectionView: Opt<CollectionView>;
+    SetSubView: (subView: any) => void;
 }
 
 export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?: X) {
@@ -30,6 +31,8 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
         private gestureDisposer?: GestureUtils.GestureEventDisposer;
         protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
         protected _mainCont?: HTMLDivElement;
+        @observable _focusFilters: Opt<string[]>; // docFilters that are overridden when previewing a link to an anchor which has docFilters set on it
+        @observable _focusRangeFilters: Opt<string[]>; // docRangeFilters that are overridden when previewing a link to an anchor which has docRangeFilters set on it
         protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
             this.dropDisposer?.();
             this.gestureDisposer?.();
@@ -45,6 +48,10 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
             this.createDashEventsTarget(ele);
         }
 
+        componentDidMount() {
+            this.props.SetSubView(this);
+        }
+
         componentWillUnmount() {
             this.gestureDisposer?.();
             this._multiTouchDisposer?.();
@@ -81,15 +88,13 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
         get childDocList() {
             return Cast(this.dataField, listSpec(Doc));
         }
-        docFilters = () => {
-            return (this.props.docFilters?.() ?? Cast(this.props.Document._docFilters, listSpec("string"), []));
-        }
-        docRangeFilters = () => {
-            return (this.props.docRangeFilters?.() ?? Cast(this.props.Document._docRangeFilters, listSpec("string"), []));
-        }
-        searchFilterDocs = () => {
-            return this.props.searchFilterDocs?.() ?? DocListCast(this.props.Document._searchFilterDocs);
-        }
+        collectionFilters = () => this._focusFilters ?? Cast(this.props.Document._docFilters, listSpec("string"), []);
+        collectionRangeDocFilters = () => this._focusRangeFilters ?? Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
+        childDocFilters = () => [...this.props.docFilters(), ...this.collectionFilters()];
+        childDocRangeFilters = () => [...(this.props.docRangeFilters?.() || []), ...this.collectionRangeDocFilters()];
+        IsFiltered = () => this.collectionFilters().length || this.collectionRangeDocFilters().length ? "hasFilter" :
+            this.props.docFilters().length || this.props.docRangeFilters().length ? "inheritsFilter" : undefined;
+        searchFilterDocs = () => this.props.searchFilterDocs?.() ?? DocListCast(this.props.Document._searchFilterDocs);
         @computed.struct get childDocs() {
             TraceMobx();
             let rawdocs: (Doc | Promise<Doc>)[] = [];
@@ -108,8 +113,8 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
             const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
             const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
 
-            const docFilters = this.docFilters();
-            const docRangeFilters = this.docRangeFilters();
+            const docFilters = this.childDocFilters();
+            const docRangeFilters = this.childDocRangeFilters();
             const searchDocs = this.searchFilterDocs();
             if (this.props.Document.dontRegisterView || (!docFilters.length && !docRangeFilters.length && !searchDocs.length)) {
                 return childDocs.filter(cd => !cd.cookies); // remove any documents that require a cookie if there are no filters to provide one
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 08b5e6bac..292dfd77c 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -32,9 +32,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
     @observable _collapsed: boolean = false;
     @observable _childClickedScript: Opt<ScriptField>;
     @observable _viewDefDivClick: Opt<ScriptField>;
-    @observable _focusDocFilters: Opt<string[]>; // fields that get overridden by a focus anchor
     @observable _focusPivotField: Opt<string>;
-    @observable _focusRangeFilters: Opt<string[]>;
 
     getAnchor = () => {
         const anchor = Docs.Create.HTMLAnchorDocument([], {
@@ -72,9 +70,9 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
     @action
     setViewSpec = (anchor: Doc, preview: boolean) => {
         if (preview) {   // if in preview, then override document's fields with view spec
+            this._focusFilters = StrListCast(Doc.GetProto(anchor).docFilters);
+            this._focusRangeFilters = StrListCast(Doc.GetProto(anchor).docRangeFilters);
             this._focusPivotField = StrCast(anchor.pivotField);
-            this._focusDocFilters = StrListCast(anchor.docFilters);
-            this._focusRangeFilters = StrListCast(anchor.docRangeFilters);
         } else if (anchor.pivotField !== undefined) {  // otherwise set document's fields based on anchor view spec
             this.layoutDoc._prevFilterIndex = 1;
             this.layoutDoc._pivotField = StrCast(anchor.pivotField);
@@ -84,8 +82,6 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
         return 0;
     }
 
-    pivotDocFilters = () => this._focusDocFilters || this.props.docFilters();
-    pivotDocRangeFilters = () => this._focusRangeFilters || this.props.docRangeFilters();
     layoutEngine = () => this._layoutEngine;
     toggleVisibility = action(() => this._collapsed = !this._collapsed);
 
@@ -139,10 +135,8 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
         return <div className="collectionTimeView-innards" key="timeline" style={{ pointerEvents: this.props.isContentActive() ? undefined : "none" }}
             onClick={this.contentsDown}>
             <CollectionFreeFormView {...this.props}
-                engineProps={{ pivotField: this.pivotField, docFilters: this.docFilters, docRangeFilters: this.docRangeFilters }}
+                engineProps={{ pivotField: this.pivotField, docFilters: this.childDocFilters, docRangeFilters: this.childDocRangeFilters }}
                 fitContentsToDoc={returnTrue}
-                docFilters={this.pivotDocFilters}
-                docRangeFilters={this.pivotDocRangeFilters}
                 childClickScript={this._childClickedScript}
                 viewDefDivClick={this._viewDefDivClick}
                 childFreezeDimensions={true}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index e225c4a11..2718cbbbf 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,4 +1,4 @@
-import { computed, observable, runInAction } from 'mobx';
+import { computed, observable, runInAction, action } from 'mobx';
 import { observer } from "mobx-react";
 import * as React from 'react';
 import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app
@@ -236,13 +236,19 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
     * Shows the filter icon if it's a user-created collection which isn't a dashboard and has some docFilters applied on it or on the current dashboard.
     */
     @computed get showFilterIcon() {
-        return this.props.Document.viewType !== CollectionViewType.Docking && !Doc.IsSystem(this.props.Document) && ((StrListCast(this.props.Document._docFilters).length || StrListCast(this.props.Document._docRangeFilters).length || StrListCast(CurrentUserUtils.ActiveDashboard._docFilters).length || StrListCast(CurrentUserUtils.ActiveDashboard._docRangeFilters).length));
+        return this.props.Document.viewType !== CollectionViewType.Docking && !Doc.IsSystem(this.props.Document) && this._subView?.IsFiltered()
     }
 
+    @observable _subView: any = undefined;
+
     render() {
         TraceMobx();
         const props: SubCollectionViewProps = {
             ...this.props,
+            SetSubView: action((subView: any) => {
+                console.log("Setting sub", subView);
+                return this._subView = subView
+            }),
             addDocument: this.addDocument,
             moveDocument: this.moveDocument,
             removeDocument: this.removeDocument,
@@ -260,8 +266,8 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
             {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
             {this.showFilterIcon ?
                 <FontAwesomeIcon icon={"filter"} size="lg"
-                    style={{ position: 'absolute', top: '1%', right: '1%', cursor: "pointer", padding: 1, color: '#18c718bd', zIndex: 1 }}
-                    onPointerDown={e => { runInAction(() => CurrentUserUtils.propertiesWidth = 250); e.stopPropagation(); }}
+                    style={{ position: 'absolute', top: '1%', right: '1%', cursor: "pointer", padding: 1, color: this.showFilterIcon === "hasFilter" ? '#18c718bd' : "orange", zIndex: 1 }}
+                    onPointerDown={action(e => { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })}
                 />
                 : (null)}
         </div>);
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index a24f1eb7a..623e0f58d 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -363,8 +363,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 PanelHeight={this.PanelHeight}
                 layerProvider={this.layerProvider}
                 styleProvider={DefaultStyleProvider}
-                docFilters={CollectionDockingView.Instance.docFilters}
-                docRangeFilters={CollectionDockingView.Instance.docRangeFilters}
+                docFilters={CollectionDockingView.Instance.childDocFilters}
+                docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
                 searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
                 addDocument={undefined}
                 removeDocument={undefined}
@@ -468,6 +468,7 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
             <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
                 <CollectionFreeFormView
                     Document={this.props.document}
+                    SetSubView={() => this}
                     CollectionView={undefined}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined}
@@ -496,8 +497,8 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
                     layerProvider={undefined}
                     addDocTab={this.props.addDocTab}
                     pinToPres={TabDocView.PinDoc}
-                    docFilters={CollectionDockingView.Instance.docFilters}
-                    docRangeFilters={CollectionDockingView.Instance.docRangeFilters}
+                    docFilters={CollectionDockingView.Instance.childDocFilters}
+                    docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
                     searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
                     fitContentsToDoc={returnTrue}
                 />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ecc93285e..ba6222605 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -110,8 +110,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @observable _timelineRef = React.createRef<Timeline>();
     @observable _marqueeRef = React.createRef<HTMLDivElement>();
     @observable _keyframeEditing = false;
-    @observable _focusFilters: Opt<string[]>; // docFilters that are overridden when previewing a link to an anchor which has docFilters set on it
-    @observable _focusRangeFilters: Opt<string[]>; // docRangeFilters that are overridden when previewing a link to an anchor which has docRangeFilters set on it
     @observable ChildDrag: DocumentView | undefined; // child document view being dragged.  needed to update drop areas of groups when a group item is dragged.
 
     @computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); }
@@ -159,8 +157,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         this.layoutDoc._viewScale = vals.scale;
     }
     freeformData = (force?: boolean) => this.fitToContent || force ? this.fitToContentVals : undefined;
-    freeformDocFilters = () => this._focusFilters;
-    freeformRangeDocFilters = () => this._focusRangeFilters;
     reverseNativeScaling = () => this.fitToContent ? true : false;
     panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document._panX);
     panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document._panY);
@@ -1030,8 +1026,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             ScreenToLocalTransform={childLayout.z ? this.getTransformOverlay : this.getTransform}
             PanelWidth={childLayout[WidthSym]}
             PanelHeight={childLayout[HeightSym]}
-            docFilters={this.freeformDocFilters}
-            docRangeFilters={this.freeformRangeDocFilters}
+            docFilters={this.childDocFilters}
+            docRangeFilters={this.childDocRangeFilters}
             searchFilterDocs={this.searchFilterDocs}
             isContentActive={this.isAnnotationOverlay ? this.props.isContentActive : returnFalse}
             isDocumentActive={this.props.childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index f3a39a262..65c345547 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -237,8 +237,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={dxf}
             focus={this.props.focus}
-            docFilters={this.docFilters}
-            docRangeFilters={this.docRangeFilters}
+            docFilters={this.childDocFilters}
+            docRangeFilters={this.childDocRangeFilters}
             searchFilterDocs={this.searchFilterDocs}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 29cb3511a..30836854a 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -236,9 +236,9 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={dxf}
             focus={this.props.focus}
-            docFilters={this.docFilters}
+            docFilters={this.childDocFilters}
             isContentActive={returnFalse}
-            docRangeFilters={this.docRangeFilters}
+            docRangeFilters={this.childDocRangeFilters}
             searchFilterDocs={this.searchFilterDocs}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 585cda729..fed64b620 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -413,8 +413,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                     isContentActive={returnTrue}
                     isDocumentActive={returnFalse}
                     ScreenToLocalTransform={this.getPreviewTransform}
-                    docFilters={this.docFilters}
-                    docRangeFilters={this.docRangeFilters}
+                    docFilters={this.childDocFilters}
+                    docRangeFilters={this.childDocRangeFilters}
                     searchFilterDocs={this.searchFilterDocs}
                     styleProvider={DefaultStyleProvider}
                     layerProvider={undefined}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c218b805e..bea219831 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -105,9 +105,9 @@ export interface DocumentViewSharedProps {
     styleProvider: Opt<StyleProviderFunc>;
     focus: DocFocusFunc;
     fitWidth?: () => boolean;
-    docFilters?: () => Opt<string[]>;
-    docRangeFilters?: () => Opt<string[]>;
-    searchFilterDocs?: () => Opt<Doc[]>;
+    docFilters: () => string[];
+    docRangeFilters: () => string[];
+    searchFilterDocs: () => Doc[];
     whenChildContentsActiveChanged: (isActive: boolean) => void;
     rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected
     addDocTab: (doc: Doc, where: string) => boolean;
-- 
cgit v1.2.3-70-g09d2


From fe78892ad8dd477779e0746918be373b9b5c15c0 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 10 Aug 2021 13:42:47 -0400
Subject: fixes for git-like to work with sidebar.  added 'lastModified' field
 for changes to x/y/width/height

---
 src/client/documents/Gitlike.ts                    | 36 ++++++++++++++++------
 src/client/views/DocumentDecorations.tsx           |  2 ++
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 ++
 src/fields/Doc.ts                                  | 12 +++++---
 4 files changed, 38 insertions(+), 14 deletions(-)

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

diff --git a/src/client/documents/Gitlike.ts b/src/client/documents/Gitlike.ts
index fddf317bc..575c984f5 100644
--- a/src/client/documents/Gitlike.ts
+++ b/src/client/documents/Gitlike.ts
@@ -1,7 +1,8 @@
-import { Doc, DocListCast, DocListCastAsync } from "../../fields/Doc";
+import { Doc, DocListCast, DocListCastAsync, Field } from "../../fields/Doc";
 import { List } from "../../fields/List";
-import { ObjectField } from "../../fields/ObjectField";
 import { Cast, DateCast } from "../../fields/Types";
+import { DateField } from "../../fields/DateField";
+import { Id } from "../../fields/FieldSymbols";
 
 // synchs matching documents on the two branches that are being merged/pulled
 // currently this just synchs the main 'fieldKey' component of the data since 
@@ -10,11 +11,22 @@ function GitlikeSynchDocs(bd: Doc, md: Doc) {
     const fieldKey = Doc.LayoutFieldKey(md);
     const bdate = DateCast(bd[`${fieldKey}-lastModified`])?.date;
     const mdate = DateCast(md[`${fieldKey}-lastModified`])?.date;
-    if (bdate === mdate || bdate > mdate) return;
     const bdproto = bd && Doc.GetProto(bd);
+    if (bdate !== mdate && bdate <= mdate) {
+        if (bdproto && md) {
+            bdproto[fieldKey] = Field.Copy(md[fieldKey]);
+            bdproto[`${fieldKey}-lastModified`] = new DateField();
+        }
+    }
+    const bldate = DateCast(bd._lastModified)?.date;
+    const mldate = DateCast(md._lastModified)?.date;
+    if (bldate === mldate || bldate > mldate) return;
     if (bdproto && md) {
-        bdproto[fieldKey] = ObjectField.MakeCopy(md[fieldKey] as ObjectField);
-        bdproto[`${fieldKey}-lastModified`] = ObjectField.MakeCopy(md[`${fieldKey}-lastModified`] as ObjectField);
+        bd.x = Field.Copy(md.x);
+        bd.y = Field.Copy(md.y);
+        bd.width = Field.Copy(md.width);
+        bd.height = Field.Copy(md.height);
+        bdproto._lastModified = new DateField();
     }
 }
 
@@ -36,8 +48,9 @@ async function GitlikePullFromMaster(branch: Doc, suffix = "") {
         const bd = branchMainDocs?.find(bd => (Cast(bd.branchOf, Doc, null) || bd) === md);
         bd && GitlikeSynchDocs(bd, md);
     });
+    const cloneMap = new Map<string, Doc>(); cloneMap.set(masterMain[Id], branch);
     // make branch clones of them, then add them to the branch
-    const newlyBranchedDocs = await Promise.all(newDocsFromMaster?.map(async md => (await Doc.MakeClone(md, false, true)).clone) || []);
+    const newlyBranchedDocs = await Promise.all(newDocsFromMaster?.map(async md => (await Doc.MakeClone(md, false, true, cloneMap)).clone) || []);
     newlyBranchedDocs.forEach(nd => {
         Doc.AddDocToList(branch, Doc.LayoutFieldKey(branch) + suffix, nd);
         nd.context = branch;
@@ -56,22 +69,26 @@ async function GitlikeMergeWithMaster(master: Doc, suffix = "") {
     branches?.map(async branch => {
         const branchChildren = await DocListCastAsync(branch[Doc.LayoutFieldKey(branch) + suffix]);
         branchChildren && await Promise.all(branchChildren.map(async bd => {
+            const cloneMap = new Map<string, Doc>(); cloneMap.set(master[Id], branch);
             // see if the branch's child exists on master.  
-            const masterChild = Cast(bd.branchOf, Doc, null) || (await Doc.MakeClone(bd, false, true)).clone;
+            const masterChild = Cast(bd.branchOf, Doc, null) || (await Doc.MakeClone(bd, false, true, cloneMap)).clone;
             // if the branch's child didn't exist on master, we make a branch clone of the child to add to master.  
             // however, since master is supposed to have the "main" clone, and branches, the "branch" clones, we have to reverse the fields
             // on the branch child and master clone.
             if (masterChild.branchOf) {
                 const branchDocProto = Doc.GetProto(bd);
                 const masterChildProto = Doc.GetProto(masterChild);
-                masterChildProto.branchOf = undefined; // the master child should not be a branch of the branch child, so unset 'branchOf'
+                const branchTitle = bd.title;
+                branchDocProto.title = masterChildProto.title;
+                masterChildProto.title = branchTitle;
+                masterChildProto.branchOf = masterChild.branchOf = undefined; // the master child should not be a branch of the branch child, so unset 'branchOf'
                 masterChildProto.branches = new List<Doc>([bd]); // the master child's branches needs to include the branch child
                 Doc.RemoveDocFromList(branchDocProto, "branches", masterChildProto);   // the branch child should not have the master child in its branch list.
                 branchDocProto.branchOf = masterChild;                                 // the branch child is now a branch of the master child
             }
             Doc.AddDocToList(master, Doc.LayoutFieldKey(master) + suffix, masterChild); // add the masterChild to master (if it's already there, this is a no-op)
             masterChild.context = master;
-            GitlikeSynchDocs(Doc.GetProto(masterChild), bd);
+            GitlikeSynchDocs(masterChild, bd);//Doc.GetProto(masterChild), bd);
         }));
         const masterChildren = await DocListCastAsync(master[Doc.LayoutFieldKey(master) + suffix]);
         masterChildren?.forEach(mc => {                      // see if any master children
@@ -93,6 +110,7 @@ export async function BranchTask(target: Doc, action: "pull" | "merge") {
     const func = action === "pull" ? GitlikePullFromMaster : GitlikeMergeWithMaster;
     await func(target, "");
     await DocListCast(target[Doc.LayoutFieldKey(target)]).forEach(async targetChild => func(targetChild, "-annotations"));
+    await DocListCast(target[Doc.LayoutFieldKey(target)]).forEach(async targetChild => func(targetChild, "-sidebar"));
 }
 
 export async function BranchCreate(target: Doc) {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index d24ab974c..118d2e7c7 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -27,6 +27,7 @@ import { LightboxView } from './LightboxView';
 import { DocumentView } from "./nodes/DocumentView";
 import React = require("react");
 import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { DateField } from '../../fields/DateField';
 
 @observer
 export class DocumentDecorations extends React.Component<{ boundsLeft: number, boundsTop: number }, { value: string }> {
@@ -367,6 +368,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
                     dW && (doc._width = actualdW);
                     dH && (doc._autoHeight = false);
                 }
+                doc._lastModified = new DateField();
             }
             const val = this._dragHeights.get(docView.layoutDoc);
             if (val) this._dragHeights.set(docView.layoutDoc, { start: val.start, lowest: Math.min(val.lowest, NumCast(docView.layoutDoc._height)) });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ba6222605..fa7e75202 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -49,6 +49,7 @@ import "./CollectionFreeFormView.scss";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
 import { DocumentType } from "../../../documents/DocumentTypes";
+import { DateField } from "../../../../fields/DateField";
 
 export const panZoomSchema = createSchema({
     _panX: "number",
@@ -257,6 +258,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 d.x = x + NumCast(d.x) - dropPos[0];
                 d.y = y + NumCast(d.y) - dropPos[1];
             }
+            d._lastModified = new DateField();
             const nd = [Doc.NativeWidth(layoutDoc), Doc.NativeHeight(layoutDoc)];
             layoutDoc._width = NumCast(layoutDoc._width, 300);
             layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? nd[1] / nd[0] * NumCast(layoutDoc._width) : 300);
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 85ea3cfa9..1eeadeedc 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -55,6 +55,9 @@ export namespace Field {
             || (field instanceof RefField)
             || (includeUndefined && field === undefined);
     }
+    export function Copy(field: any) {
+        return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field;
+    }
 }
 export type Field = number | string | boolean | ObjectField | RefField;
 export type Opt<T> = T | undefined;
@@ -537,7 +540,7 @@ export namespace Doc {
             const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
             const field = ProxyField.WithoutProxy(() => doc[key]);
             const copyObjectField = async (field: ObjectField) => {
-                const list = Cast(doc[key], listSpec(Doc));
+                const list = await Cast(doc[key], listSpec(Doc));
                 const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc);
                 if (docs !== undefined && docs.length) {
                     const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch)));
@@ -589,11 +592,10 @@ export namespace Doc {
         }
         return copy;
     }
-    export async function MakeClone(doc: Doc, dontCreate: boolean = false, asBranch = false) {
-        const cloneMap = new Map<string, Doc>();
+    export async function MakeClone(doc: Doc, dontCreate: boolean = false, asBranch = false, cloneMap: Map<string, Doc> = new Map()) {
         const linkMap = new Map<Doc, Doc>();
         const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = [];
-        const copy = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ["context", "annotationOn", "cloneOf", "branches", "branchOf"], dontCreate, asBranch);
+        const copy = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ["cloneOf", "branches", "branchOf"], dontCreate, asBranch);
         Array.from(linkMap.entries()).map((links: Doc[]) => LinkManager.Instance.addLink(links[1], true));
         rtfMap.map(({ copy, key, field }) => {
             const replacer = (match: any, attr: string, id: string, offset: any, string: any) => {
@@ -1385,7 +1387,7 @@ Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); });
 Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); });
 Scripting.addGlobal(function copyDragFactory(dragFactory: Doc) { return Doc.copyDragFactory(dragFactory); });
 Scripting.addGlobal(function delegateDragFactory(dragFactory: Doc) { return Doc.delegateDragFactory(dragFactory); });
-Scripting.addGlobal(function copyField(field: any) { return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field; });
+Scripting.addGlobal(function copyField(field: any) { return Field.Copy(field); });
 Scripting.addGlobal(function docList(field: any) { return DocListCast(field); });
 Scripting.addGlobal(function setInPlace(doc: any, field: any, value: any) { return Doc.SetInPlace(doc, field, value, false); });
 Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); });
-- 
cgit v1.2.3-70-g09d2

