aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionTreeView.tsx
diff options
context:
space:
mode:
authorgeireann <geireann.lindfield@gmail.com>2021-08-27 14:19:25 -0400
committergeireann <geireann.lindfield@gmail.com>2021-08-27 14:19:25 -0400
commitbe4fd2492ad706f30af28f33133a4df0e8049e12 (patch)
treee33b32f54be50122ed16c07d2b6f6b2e79239cb4 /src/client/views/collections/CollectionTreeView.tsx
parentc5e96c72fcf149b9bcfe5f7f7a9c714de1d5fd9a (diff)
parent7c83bc30b3a6ed6061ef68bcef6a0e8941668b3c (diff)
Merge branch 'master' into schema-view-En-Hua
Diffstat (limited to 'src/client/views/collections/CollectionTreeView.tsx')
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 82c8a9114..89d42439e 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,15 +1,16 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, reaction, IReactionDisposer, observable } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { DataSym, Doc, DocListCast, HeightSym, Opt, StrListCast, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
-import { List } from '../../../fields/List';
-import { Document } from '../../../fields/Schema';
+import { InkTool } from '../../../fields/InkField';
+import { Document, listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
import { DocUtils } from '../../documents/Documents';
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType } from "../../util/DragManager";
import { SelectionManager } from '../../util/SelectionManager';
@@ -25,8 +26,6 @@ import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import { TreeView } from "./TreeView";
import React = require("react");
-import { InkTool } from '../../../fields/InkField';
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
const _global = (window /* browser */ || global /* node */) as any;
export type collectionTreeViewProps = {
@@ -52,6 +51,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
@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"; }
+ @computed get dashboardMode() { return this.doc === Doc.UserDoc().myDashboards; }
// these should stay in synch with counterparts in DocComponent.ts ViewBoxAnnotatableComponent
@observable _isAnyChildContentActive = false;
@@ -61,7 +61,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
this.props.isSelected(outsideReaction) || this._isAnyChildContentActive ||
this.props.rootSelected(outsideReaction)) ? true : false)
+ isDisposing = false;
componentWillUnmount() {
+ this.isDisposing = true;
super.componentWillUnmount();
this.treedropDisposer?.();
Object.values(this._disposers).forEach(disposer => disposer?.());
@@ -76,15 +78,16 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
refList: Set<any> = new Set();
observer: any;
computeHeight = () => {
- 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);
+ if (this.isDisposing) return;
+ const bodyHeight = Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), this.paddingTop() + this.paddingBot());
+ this.layoutDoc._autoHeightMargins = bodyHeight;
+ this.props.setHeight(this.documentTitleHeight() + bodyHeight);
}
unobserveHeight = (ref: any) => {
this.refList.delete(ref);
this.rootDoc.autoHeight && this.computeHeight();
}
- observerHeight = (ref: any) => {
+ observeHeight = (ref: any) => {
if (ref) {
this.refList.add(ref);
this.observer = new _global.ResizeObserver(action((entries: any) => {
@@ -154,7 +157,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
!existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "mouse-pointer" });
}
}
- onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {});
+ onTreeDrop = (e: React.DragEvent, addDocs?: (docs: Doc[]) => void) => this.onExternalDrop(e, {}, addDocs);
@undoBatch
makeTextCollection = (childDocs: Doc[]) => {
@@ -199,6 +202,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
NativeWidth={this.documentTitleWidth}
NativeHeight={this.documentTitleHeight}
focus={this.props.focus}
+ treeViewDoc={this.props.Document}
ScreenToLocalTransform={this.titleTransform}
docFilters={returnEmptyFilter}
docRangeFilters={returnEmptyFilter}
@@ -215,6 +219,11 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
/>
</div>;
}
+ childContextMenuItems = () => {
+ const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
+ const filterScripts = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
+ return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: filterScripts[i], label }));
+ }
@computed get treeViewElements() {
TraceMobx();
const dropAction = StrCast(this.doc.childDropAction) as dropActionType;
@@ -246,12 +255,14 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
true,
this.whenChildContentsActiveChanged,
this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null),
- this.observerHeight,
- this.unobserveHeight);
+ this.observeHeight,
+ this.unobserveHeight,
+ this.childContextMenuItems()
+ );
}
@computed get titleBar() {
const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle;
- return hideTitle ? (null) : (this.doc.treeViewType === "outline" ? this.documentTitle : this.editableTitle)(this.treeChildren);
+ return hideTitle ? (null) : (this.outlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren);
}
@computed get renderClearButton() {
@@ -261,30 +272,42 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
</button>
</div >;
}
+ @computed get nativeWidth() { return Doc.NativeWidth(this.Document, undefined, true); }
+ @computed get nativeHeight() { return Doc.NativeHeight(this.Document, undefined, true); }
+ @computed get contentScaling() {
+ const nw = this.nativeWidth;
+ const nh = this.nativeHeight;
+ const hscale = nh ? this.props.PanelHeight() / nh : 1;
+ const wscale = nw ? this.props.PanelWidth() / nw : 1;
+ return wscale < hscale ? wscale : hscale;
+ }
paddingX = () => NumCast(this.doc._xPadding, 15);
paddingTop = () => NumCast(this.doc._yPadding, 20);
+ paddingBot = () => NumCast(this.doc._yPadding, 20);
documentTitleWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.panelWidth());
- documentTitleHeight = () => Math.min(this.layoutDoc?.[HeightSym](), (StrCast(this.layoutDoc?._fontSize) ? Number(StrCast(this.layoutDoc?._fontSize, "32px").replace("px", "")) : NumCast(this.layoutDoc?._fontSize)) * 2);
+ documentTitleHeight = () => (this.layoutDoc?.[HeightSym]() || 0) - NumCast(this.layoutDoc.autoHeightMargins);
titleTransform = () => this.props.ScreenToLocalTransform().translate(-NumCast(this.doc._xPadding, 10), -NumCast(this.doc._yPadding, 20));
truncateTitleWidth = () => this.treeViewtruncateTitleWidth;
onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick);
- panelWidth = () => this.props.PanelWidth() - 2 * this.paddingX();
+ panelWidth = () => (this.props.PanelWidth() - 2 * this.paddingX()) * (this.props.scaling?.() || 1);
render() {
TraceMobx();
const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor);
const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined;
return !(this.doc instanceof Doc) || !this.treeChildren ? (null) :
- <div className="collectionTreeView-container" onContextMenu={this.onContextMenu}>
+ <div className="collectionTreeView-container"
+ style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}}
+ onContextMenu={this.onContextMenu}>
<div className="collectionTreeView-dropTarget"
- style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
+ style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
onWheel={e => e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
{this.titleBar}
{this.renderClearButton}
- <ul className="no-indent">
+ <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} >
{this.treeViewElements}
</ul>
</div >