aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionSubView.tsx18
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx21
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/collections/TreeView.scss41
-rw-r--r--src/client/views/collections/TreeView.tsx37
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx2
6 files changed, 79 insertions, 42 deletions
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a5d679df0..b998555d8 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -90,7 +90,8 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
searchFilterDocs = () => {
return [...this.props.searchFilterDocs(), ...DocListCast(this.props.Document._searchFilterDocs)];
}
- @computed get childDocs() {
+ @computed.struct get childDocs() {
+ TraceMobx();
let rawdocs: (Doc | Promise<Doc>)[] = [];
if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list;
rawdocs = [this.dataField];
@@ -114,10 +115,14 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
return childDocs.filter(cd => !cd.cookies); // remove any documents that require a cookie if there are no filters to provide one
}
+ // console.log(CurrentUserUtils.ActiveDashboard._docFilters);
+ // if (!this.props.Document._docFilters && this.props.Document.currentFilter) {
+ // (this.props.Document.currentFilter as Doc).filterBoolean = (this.props.ContainingCollectionDoc?.currentFilter as Doc)?.filterBoolean;
+ // }
const docsforFilter: Doc[] = [];
childDocs.forEach((d) => {
- if (DocUtils.Excluded(d, docFilters)) return;
- let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0));
+ // if (DocUtils.Excluded(d, docFilters)) return;
+ let notFiltered = d.z || Doc.IsSystem(d) || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length > 0));
const fieldKey = Doc.LayoutFieldKey(d);
const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
const data = d[annos ? fieldKey + "-annotations" : fieldKey];
@@ -125,13 +130,13 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
let subDocs = DocListCast(data);
if (subDocs.length > 0) {
let newarray: Doc[] = [];
- notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, docFilters, docRangeFilters, viewSpecScript).length);
+ notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, docFilters, docRangeFilters, viewSpecScript, d).length);
while (subDocs.length > 0 && !notFiltered) {
newarray = [];
subDocs.forEach((t) => {
const fieldKey = Doc.LayoutFieldKey(t);
const annos = !Field.toString(Doc.LayoutField(t) as Field).includes("CollectionView");
- notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([t], docFilters, docRangeFilters, viewSpecScript).length));
+ notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([t], docFilters, docRangeFilters, viewSpecScript, d).length));
DocListCast(t[annos ? fieldKey + "-annotations" : fieldKey]).forEach((newdoc) => newarray.push(newdoc));
});
subDocs = newarray;
@@ -474,5 +479,6 @@ import { CollectionView, CollectionViewType, CollectionViewProps } from "./Colle
import { SelectionManager } from "../../util/SelectionManager";
import { OverlayView } from "../OverlayView";
import { Hypothesis } from "../../util/HypothesisUtils";
-import { GetEffectiveAcl } from "../../../fields/util";
+import { GetEffectiveAcl, TraceMobx } from "../../../fields/util";
+import { FilterBox } from "../nodes/FilterBox";
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 5a4864d2d..82c8a9114 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -49,7 +49,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
@computed get doc() { return this.props.Document; }
@computed get dataDoc() { return this.props.DataDoc || this.doc; }
@computed get treeViewtruncateTitleWidth() { return NumCast(this.doc.treeViewTruncateTitleWidth, this.panelWidth()); }
- @computed get treeChildren() { return this.props.childDocuments || this.childDocs; }
+ @computed get treeChildren() { TraceMobx(); return this.props.childDocuments || this.childDocs; }
@computed get outlineMode() { return this.doc.treeViewType === "outline"; }
@computed get fileSysMode() { return this.doc.treeViewType === "fileSystem"; }
@@ -67,19 +67,23 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
Object.values(this._disposers).forEach(disposer => disposer?.());
}
- componentWillMount() {
+ componentDidMount() {
this._disposers.autoheight = reaction(() => this.rootDoc.autoHeight,
auto => auto && this.computeHeight(),
- { fireImmediately: true })
+ { fireImmediately: true });
}
refList: Set<any> = new Set();
observer: any;
computeHeight = () => {
- this.rootDoc._height = this.paddingTop() + 26/* bcz: ugh: title bar height hack ... get ref and compute instead */ +
+ const hgt = this.paddingTop() + 26/* bcz: ugh: title bar height hack ... get ref and compute instead */ +
Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0);
+ this.props.setHeight(hgt);
+ }
+ unobserveHeight = (ref: any) => {
+ this.refList.delete(ref);
+ this.rootDoc.autoHeight && this.computeHeight();
}
- unobserveHeight = (ref: any) => this.refList.delete(ref);
observerHeight = (ref: any) => {
if (ref) {
this.refList.add(ref);
@@ -111,15 +115,14 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
const targetDataDoc = this.doc[DataSym];
const value = DocListCast(targetDataDoc[this.props.fieldKey]);
const result = value.filter(v => !docs.includes(v));
- SelectionManager.DeselectAll();
+ if ((doc instanceof Doc ? [doc] : doc).some(doc => SelectionManager.Views().some(dv => Doc.AreProtosEqual(dv.rootDoc, doc)))) SelectionManager.DeselectAll();
if (result.length !== value.length) {
const ind = targetDataDoc[this.props.fieldKey].indexOf(doc);
const prev = ind && targetDataDoc[this.props.fieldKey][ind - 1];
- targetDataDoc[this.props.fieldKey] = new List<Doc>(result);
+ this.props.removeDocument?.(doc);
if (ind > 0) {
FormattedTextBox.SelectOnLoad = prev[Id];
- const prevView = DocumentManager.Instance.getDocumentView(prev, this.props.CollectionView);
- prevView?.select(false);
+ DocumentManager.Instance.getDocumentView(prev, this.props.CollectionView)?.select(false);
}
return true;
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 21dd4b206..4dc0ee3e6 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,4 +1,4 @@
-import { action, computed, observable } from 'mobx';
+import { computed, observable } 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
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index bf896b8d3..5b0c04f33 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -8,6 +8,7 @@
width: 100%;
overflow: hidden;
}
+
.treeView-container,
.treeView-container-active {
.bullet-outline {
@@ -21,21 +22,26 @@
.treeView-bulletIcons {
width: $TREE_BULLET_WIDTH;
+
.treeView-expandIcon {
display: none;
left: -10px;
position: absolute;
}
+
.treeView-checkIcon {
- left: -10px;
+ left: 3.5px;
+ top: 2px;
position: absolute;
}
+
&:hover {
.treeView-expandIcon {
display: unset;
}
}
}
+
.bullet {
position: relative;
width: $TREE_BULLET_WIDTH;
@@ -46,9 +52,11 @@
border-radius: 4px;
}
}
+
.treeView-container-active {
z-index: 100;
position: relative;
+
.formattedTextbox-sidebar {
background-color: #ffff001f !important;
height: 500px !important;
@@ -71,7 +79,8 @@
display: flex;
overflow: hidden;
}
-.treeView-border{
+
+.treeView-border {
border-left: dashed 1px #00000042;
}
@@ -79,15 +88,20 @@
.treeView-header {
border: transparent 1px solid;
display: flex;
+
//align-items: center;
::-webkit-scrollbar {
- display: none;
+ display: none;
}
+
.formattedTextBox-cont {
- .formattedTextbox-sidebar, .formattedTextbox-sidebar-inking {
+
+ .formattedTextbox-sidebar,
+ .formattedTextbox-sidebar-inking {
overflow: visible !important;
border-left: unset;
}
+
overflow: visible !important;
}
@@ -105,12 +119,18 @@
margin-left: 0.25rem;
opacity: 0.75;
- >svg, .styleProvider-treeView-lock, .styleProvider-treeView-hide, .styleProvider-treeView-lock-active, .styleProvider-treeView-hide-active {
+ >svg,
+ .styleProvider-treeView-lock,
+ .styleProvider-treeView-hide,
+ .styleProvider-treeView-lock-active,
+ .styleProvider-treeView-hide-active {
margin-left: 0.25rem;
- margin-right: 0.25rem;
+ margin-right: 0.25rem;
}
-
- >svg, .styleProvider-treeView-lock, .styleProvider-treeView-hide {
+
+ >svg,
+ .styleProvider-treeView-lock,
+ .styleProvider-treeView-hide {
display: none;
}
}
@@ -135,7 +155,10 @@
}
.right-buttons-container {
- >svg, .styleProvider-treeView-lock, .styleProvider-treeView-hide {
+
+ >svg,
+ .styleProvider-treeView-lock,
+ .styleProvider-treeView-hide {
display: inherit;
}
}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 2c3a6c0d7..ce3ba7981 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -21,7 +21,7 @@ import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
import { EditableView } from "../EditableView";
import { TREE_BULLET_WIDTH } from '../globalCssVariables.scss';
-import { DocumentView, DocumentViewProps, StyleProviderFunc } from '../nodes/DocumentView';
+import { DocumentView, DocumentViewProps, StyleProviderFunc, DocumentViewInternal } from '../nodes/DocumentView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
import { KeyValueBox } from '../nodes/KeyValueBox';
@@ -152,7 +152,6 @@ export class TreeView extends React.Component<TreeViewProps> {
} else {
this.props.addDocTab(this.props.document, "add:right");
}
- docView?.select(false);
}
constructor(props: any) {
super(props);
@@ -174,7 +173,7 @@ export class TreeView extends React.Component<TreeViewProps> {
componentWillUnmount() {
this._selDisposer?.();
- this._treeEle && this.props.unobserveHeight(this._treeEle)
+ this._treeEle && this.props.unobserveHeight(this._treeEle);
document.removeEventListener("pointermove", this.onDragMove, true);
document.removeEventListener("pointermove", this.onDragUp, true);
}
@@ -442,7 +441,7 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get renderBullet() {
TraceMobx();
- const iconType = this.doc.isFolder ? (this.treeViewOpen ? "chevron-down" : "chevron-right") : Doc.toIcon(this.doc);
+ const iconType = this.props.treeView.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ":open" : "")) || "question";
const checked = this.onCheckedClick ? (this.doc.treeViewChecked ?? "unchecked") : undefined;
return <div className={`bullet${this.props.treeView.outlineMode ? "-outline" : ""}`} key={"bullet"}
title={this.childDocs?.length ? `click to see ${this.childDocs?.length} items` : "view fields"}
@@ -483,22 +482,29 @@ export class TreeView extends React.Component<TreeViewProps> {
}
@computed get headerElements() {
- return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null)
+ return this.props.treeViewHideHeaderFields() || this.doc.treeViewHideHeaderFields ? (null)
: <>
- <FontAwesomeIcon key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />
- {this.doc.treeViewExpandedViewLock ? (null) :
+ {this.doc.hideContextMenu ? (null) : <FontAwesomeIcon key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />}
+ {this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? (null) :
<span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
{this.treeViewExpandedView}
</span>}
</>;
}
- showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
- contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : this.doc.isFolder ?
- [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] :
- this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ?
- [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }] :
- [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }]
+ showContextMenu = (e: React.MouseEvent) => {
+ DocumentViewInternal.SelectAfterContextMenu = false;
+ simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
+ DocumentViewInternal.SelectAfterContextMenu = true;
+ }
+ contextMenuItems = () => {
+ const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" };
+ return this.doc.isFolder ? [makeFolder] :
+ Doc.IsSystem(this.doc) ? [] :
+ this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ?
+ [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }, makeFolder] :
+ [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }];
+ }
onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick);
@@ -522,7 +528,6 @@ export class TreeView extends React.Component<TreeViewProps> {
}}>
{StrCast(doc?.title)}
</div>;
- case StyleProp.Decorations: return (null);
default: return this.props?.treeView?.props.styleProvider?.(doc, props, property);
}
}
@@ -542,7 +547,7 @@ export class TreeView extends React.Component<TreeViewProps> {
}
}
}
- titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - treeBulletWidth()));
+ titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - 2 * treeBulletWidth()));
/**
* Renders the EditableView title element for placement into the tree.
@@ -726,7 +731,7 @@ export class TreeView extends React.Component<TreeViewProps> {
return this.props.renderedIds.indexOf(this.doc[Id]) !== -1 ? "<" + this.doc.title + ">" : // just print the title of documents we've previously rendered in this hierarchical path to avoid cycles
<div className={`treeView-container${this.props.isContentActive() ? "-active" : ""}`}
ref={this.createTreeDropTarget}
- onPointerDown={e => this.props.isContentActive(true) && SelectionManager.DeselectAll()}
+ //onPointerDown={e => this.props.isContentActive(true) && SelectionManager.DeselectAll()} // bcz: this breaks entering a text filter in a filterBox since it deselects the filter's target document
onKeyDown={this.onKeyDown}>
<li className="collection-child">
{hideTitle && this.doc.type !== DocumentType.RTF ?
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index d14b68fa7..a4f129b8c 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -101,7 +101,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
else if (e.key === ":") {
DocUtils.addDocumentCreatorMenuItems(this.props.addLiveTextDocument, this.props.addDocument || returnFalse, x, y);
- cm.displayMenu(this._downX, this._downY);
+ cm.displayMenu(this._downX, this._downY, undefined, true);
e.stopPropagation();
} else if (e.key === "a" && (e.ctrlKey || e.metaKey)) {
e.preventDefault();