aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionTreeView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionTreeView.tsx')
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx86
1 files changed, 44 insertions, 42 deletions
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 50f03005c..882a0f144 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,12 +1,13 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faAngleRight, faCamera, faExpand, faTrash, faBell, faCaretDown, faCaretRight, faArrowsAltH, faCaretSquareDown, faCaretSquareRight, faTrashAlt, faPlus, faMinus } from '@fortawesome/free-solid-svg-icons';
+import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, trace, untracked } from "mobx";
+import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, WidthSym, Opt, Field } from '../../../new_fields/Doc';
+import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
import { Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { Document, listSpec } from '../../../new_fields/Schema';
+import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
import { emptyFunction, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
@@ -17,18 +18,16 @@ import { SelectionManager } from '../../util/SelectionManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from "../EditableView";
import { MainView } from '../MainView';
+import { KeyValueBox } from '../nodes/KeyValueBox';
import { Templates } from '../Templates';
import { CollectionViewType } from './CollectionBaseView';
-import { CollectionDockingView } from './CollectionDockingView';
import { CollectionSchemaPreview } from './CollectionSchemaView';
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
-import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { KeyValueBox } from '../nodes/KeyValueBox';
-import { ContextMenuProps } from '../ContextMenuItem';
export interface TreeViewProps {
@@ -37,9 +36,10 @@ export interface TreeViewProps {
containingCollection: Doc;
renderDepth: number;
deleteDoc: (doc: Doc) => boolean;
+ ruleProvider: Doc | undefined;
moveDocument: DragManager.MoveFunction;
dropAction: "alias" | "copy" | undefined;
- addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void;
+ addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean;
pinToPres: (document: Doc) => void;
panelWidth: () => number;
panelHeight: () => number;
@@ -52,6 +52,7 @@ export interface TreeViewProps {
active: () => boolean;
showHeaderFields: () => boolean;
preventTreeViewOpen: boolean;
+ renderedIds: string[];
}
library.add(faTrashAlt);
@@ -80,7 +81,7 @@ class TreeView extends React.Component<TreeViewProps> {
private _header?: React.RefObject<HTMLDivElement> = React.createRef();
private _treedropDisposer?: DragManager.DragDropDisposer;
private _dref = React.createRef<HTMLDivElement>();
- get defaultExpandedView() { return this.childDocs ? this.fieldKey : "fields"; }
+ get defaultExpandedView() { return this.childDocs ? this.fieldKey : this.props.document.defaultExpandedView ? StrCast(this.props.document.defaultExpandedView) : ""; }
@observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
@computed get treeViewOpen() { return (BoolCast(this.props.document.treeViewOpen) && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = c; }
@@ -176,7 +177,7 @@ class TreeView extends React.Component<TreeViewProps> {
SetValue={undoBatch((value: string) => (Doc.GetProto(this.dataDoc)[key] = value) ? true : true)}
OnFillDown={undoBatch((value: string) => {
Doc.GetProto(this.dataDoc)[key] = value;
- let doc = this.props.document.detailedLayout instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.detailedLayout)) : undefined;
+ let doc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
if (!doc) doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
TreeView.loadId = doc[Id];
return this.props.addDocument(doc);
@@ -199,6 +200,7 @@ class TreeView extends React.Component<TreeViewProps> {
ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" });
}
ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
+ ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" });
ContextMenu.Instance.displayMenu(e.pageX > 156 ? e.pageX - 156 : 0, e.pageY - 15);
e.stopPropagation();
e.preventDefault();
@@ -215,7 +217,7 @@ class TreeView extends React.Component<TreeViewProps> {
if (de.data instanceof DragManager.LinkDragData) {
let sourceDoc = de.data.linkSourceDocument;
let destDoc = this.props.document;
- DocUtils.MakeLink(sourceDoc, destDoc);
+ DocUtils.MakeLink({doc:sourceDoc}, {doc:destDoc});
e.stopPropagation();
}
if (de.data instanceof DragManager.DocumentDragData) {
@@ -247,8 +249,8 @@ class TreeView extends React.Component<TreeViewProps> {
}
docWidth = () => {
let aspect = NumCast(this.props.document.nativeHeight) / NumCast(this.props.document.nativeWidth);
- if (aspect) return Math.min(this.props.document[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 5));
- return NumCast(this.props.document.nativeWidth) ? Math.min(this.props.document[WidthSym](), this.props.panelWidth() - 5) : this.props.panelWidth() - 5;
+ if (aspect) return Math.min(this.props.document[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 20));
+ return NumCast(this.props.document.nativeWidth) ? Math.min(this.props.document[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
}
docHeight = () => {
let bounds = this.boundsOfCollectionDocument;
@@ -274,7 +276,9 @@ class TreeView extends React.Component<TreeViewProps> {
let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
DocListCast(contents), this.props.treeViewId, doc, undefined, key, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen);
+ this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
+ this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+ [...this.props.renderedIds, doc[Id]]);
} else {
contentElement = <EditableView
key="editableView"
@@ -306,7 +310,8 @@ class TreeView extends React.Component<TreeViewProps> {
TreeView.GetChildElements(docs as Doc[], this.props.treeViewId, this.props.document.layout as Doc,
this.resolvedDataDoc, expandKey, addDoc, remDoc, this.move,
this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
- this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen)}
+ this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+ [...this.props.renderedIds, this.props.document[Id]])}
</ul >;
} else if (this.treeViewExpandedView === "fields") {
return <ul><div ref={this._dref} style={{ display: "inline-block" }} key={this.props.document[Id] + this.props.document.title}>
@@ -320,10 +325,12 @@ class TreeView extends React.Component<TreeViewProps> {
DataDocument={this.resolvedDataDoc}
renderDepth={this.props.renderDepth}
showOverlays={this.noOverlays}
+ ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
fitToBox={this.boundsOfCollectionDocument !== undefined}
- width={this.docWidth}
- height={this.docHeight}
+ PanelWidth={this.docWidth}
+ PanelHeight={this.docHeight}
getTransform={this.docTransform}
+ CollectionDoc={this.props.containingCollection}
CollectionView={undefined}
addDocument={emptyFunction as any}
moveDocument={this.props.moveDocument}
@@ -340,7 +347,7 @@ class TreeView extends React.Component<TreeViewProps> {
@computed
get renderBullet() {
- return <div className="bullet" title="view inline" onClick={action(() => this.treeViewOpen = !this.treeViewOpen)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
+ return <div className="bullet" title="view inline" onClick={action((e: React.MouseEvent) => { this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
{<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
</div>;
}
@@ -373,6 +380,7 @@ class TreeView extends React.Component<TreeViewProps> {
style={{
color: this.props.document.isMinimized ? "red" : "black",
background: Doc.IsBrushed(this.props.document) ? "#06121212" : "0",
+ fontWeight: this.props.document.search_string ? "bold" : undefined,
outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined,
pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
}} >
@@ -391,13 +399,13 @@ class TreeView extends React.Component<TreeViewProps> {
{this.renderTitle}
</div>
<div className="treeViewItem-border">
- {!this.treeViewOpen ? (null) : this.renderContent}
+ {!this.treeViewOpen || this.props.renderedIds.indexOf(this.props.document[Id]) !== -1 ? (null) : this.renderContent}
</div>
</li>
</div>;
}
public static GetChildElements(
- docList: Doc[],
+ docs: Doc[],
treeViewId: string,
containingCollection: Doc,
dataDoc: Doc | undefined,
@@ -406,7 +414,7 @@ class TreeView extends React.Component<TreeViewProps> {
remove: ((doc: Doc) => boolean),
move: DragManager.MoveFunction,
dropAction: dropActionType,
- addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void,
+ addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean,
pinToPres: (document: Doc) => void,
screenToLocalXf: () => Transform,
outerXf: () => { translateX: number, translateY: number },
@@ -414,21 +422,12 @@ class TreeView extends React.Component<TreeViewProps> {
panelWidth: () => number,
renderDepth: number,
showHeaderFields: () => boolean,
- preventTreeViewOpen: boolean
+ preventTreeViewOpen: boolean,
+ renderedIds: string[]
) {
- let docs = docList.filter(child => !child.excludeFromLibrary && child.opacity !== 0);
- let viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
+ const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
if (viewSpecScript) {
- let script = viewSpecScript.script;
- docs = docs.filter(d => {
- let res = script.run({ doc: d });
- if (res.success) {
- return res.result;
- }
- else {
- console.log(res.error);
- }
- });
+ docs = docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
}
let ascending = Cast(containingCollection.sortAscending, "boolean", null);
@@ -485,6 +484,7 @@ class TreeView extends React.Component<TreeViewProps> {
dataDoc={pair.data}
containingCollection={containingCollection}
treeViewId={treeViewId}
+ ruleProvider={containingCollection.isRuleProvider && pair.layout.type !== DocumentType.TEXT ? containingCollection : containingCollection.ruleProvider as Doc}
key={child[Id]}
indentDocument={indent}
renderDepth={renderDepth}
@@ -501,7 +501,8 @@ class TreeView extends React.Component<TreeViewProps> {
parentKey={key}
active={active}
showHeaderFields={showHeaderFields}
- preventTreeViewOpen={preventTreeViewOpen} />;
+ preventTreeViewOpen={preventTreeViewOpen}
+ renderedIds={renderedIds} />;
});
}
}
@@ -537,7 +538,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
}
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
- if (!e.isPropagationStopped() && this.props.Document.workspaceLibrary) { // excludeFromLibrary means this is the user document
+ if (!e.isPropagationStopped() && this.props.Document.workspaceLibrary) {
ContextMenu.Instance.addItem({ description: "Create Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" });
ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.remove(this.props.Document), icon: "minus" });
e.stopPropagation();
@@ -552,8 +553,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
outerXf = () => Utils.GetScreenTransform(this._mainEle!);
onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {});
openNotifsCol = () => {
- if (CollectionTreeView.NotifsCol && CollectionDockingView.Instance) {
- CollectionDockingView.Instance.AddRightSplit(CollectionTreeView.NotifsCol, undefined);
+ if (CollectionTreeView.NotifsCol) {
+ this.props.addDocTab(CollectionTreeView.NotifsCol, undefined, "onRight");
}
}
@@ -591,18 +592,19 @@ export class CollectionTreeView extends CollectionSubView(Document) {
<div id="body" className="collectionTreeView-dropTarget"
style={{ overflow: "auto", background: StrCast(this.props.Document.backgroundColor, "lightgray") }}
onContextMenu={this.onContextMenu}
- onWheel={(e: React.WheelEvent) => (e.target as any).scrollHeight > (e.target as any).clientHeight && e.stopPropagation()}
+ onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
<EditableView
contents={this.resolvedDataDoc.title}
display={"block"}
- height={72}
+ maxHeight={72}
+ height={"auto"}
GetValue={() => StrCast(this.resolvedDataDoc.title)}
SetValue={undoBatch((value: string) => (Doc.GetProto(this.resolvedDataDoc).title = value) ? true : true)}
OnFillDown={undoBatch((value: string) => {
Doc.GetProto(this.props.Document).title = value;
- let doc = this.props.Document.detailedLayout instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.detailedLayout)) : undefined;
+ let doc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
if (!doc) doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
TreeView.loadId = doc[Id];
Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false);
@@ -614,7 +616,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
this.outerXf, this.props.active, this.props.PanelWidth, this.props.renderDepth, () => this.props.Document.chromeStatus !== "disabled",
- BoolCast(this.props.Document.preventTreeViewOpen))
+ BoolCast(this.props.Document.preventTreeViewOpen), [])
}
</ul>
</div >