diff options
Diffstat (limited to 'src/client/views/collections/CollectionTreeView.tsx')
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 192 |
1 files changed, 98 insertions, 94 deletions
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 288fa8794..3e99af724 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,18 +1,18 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -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, runInAction, untracked } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, 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, ScriptCast, StrCast } from '../../../new_fields/Types'; +import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc'; +import { Id } from '../../../fields/FieldSymbols'; +import { List } from '../../../fields/List'; +import { PrefetchProxy } from '../../../fields/Proxy'; +import { Document, listSpec } from '../../../fields/Schema'; +import { ComputedField, ScriptField } from '../../../fields/ScriptField'; +import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from "../../documents/DocumentTypes"; import { DocumentManager } from '../../util/DocumentManager'; +import { SnappingManager } from '../../util/SnappingManager'; import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from '../../util/SelectionManager'; @@ -31,8 +31,8 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { CollectionViewType } from './CollectionView'; import React = require("react"); -import { PrefetchProxy } from '../../../new_fields/Proxy'; - +import { makeTemplate } from '../../util/DropConverter'; +import { TraceMobx } from '../../../fields/util'; export interface TreeViewProps { document: Doc; @@ -41,7 +41,7 @@ export interface TreeViewProps { containingCollection: Doc; prevSibling?: Doc; renderDepth: number; - deleteDoc: (doc: Doc) => boolean; + deleteDoc: (doc: Doc | Doc[]) => boolean; moveDocument: DragManager.MoveFunction; dropAction: dropActionType; addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean; @@ -49,7 +49,7 @@ export interface TreeViewProps { panelWidth: () => number; panelHeight: () => number; ChromeHeight: undefined | (() => number); - addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; + addDocument: (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => boolean; indentDocument?: () => void; outdentDocument?: () => void; ScreenToLocalTransform: () => Transform; @@ -60,24 +60,12 @@ export interface TreeViewProps { active: (outsideReaction?: boolean) => boolean; treeViewHideHeaderFields: () => boolean; treeViewPreventOpen: boolean; - renderedIds: string[]; + renderedIds: string[]; // list of document ids rendered used to avoid unending expansion of items in a cycle onCheckedClick?: ScriptField; onChildClick?: ScriptField; ignoreFields?: string[]; } -library.add(faTrashAlt); -library.add(faAngleRight); -library.add(faBell); -library.add(faTrash); -library.add(faCamera); -library.add(faExpand); -library.add(faCaretDown); -library.add(faCaretRight); -library.add(faCaretSquareDown); -library.add(faCaretSquareRight); -library.add(faArrowsAltH); -library.add(faPlus, faMinus); @observer /** * Renders a treeView of a collection of documents @@ -88,66 +76,59 @@ library.add(faPlus, faMinus); * treeViewExpandedView : name of field whose contents are being displayed as the document's subtree */ class TreeView extends React.Component<TreeViewProps> { + static _editTitleScript: ScriptField | undefined; private _header?: React.RefObject<HTMLDivElement> = React.createRef(); private _treedropDisposer?: DragManager.DragDropDisposer; private _dref = React.createRef<HTMLDivElement>(); private _tref = React.createRef<HTMLDivElement>(); + private _docRef = React.createRef<DocumentView>(); get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive - get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, "fields"); } @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state set treeViewOpen(c: boolean) { if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = this._overrideTreeViewOpen = c; } - @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && BoolCast(this.props.document.treeViewOpen)) || this._overrideTreeViewOpen; } + @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.props.document.treeViewPreventOpen && BoolCast(this.props.document.treeViewOpen)) || this._overrideTreeViewOpen; } @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, this.defaultExpandedView); } @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); } - @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; } + @computed get dataDoc() { return this.props.document[DataSym]; } @computed get fieldKey() { const splits = StrCast(Doc.LayoutField(this.props.document)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; } childDocList(field: string) { const layout = Doc.LayoutField(this.props.document) instanceof Doc ? Doc.LayoutField(this.props.document) as Doc : undefined; - return ((this.props.dataDoc ? Cast(this.props.dataDoc[field], listSpec(Doc)) : undefined) || - (layout ? Cast(layout[field], listSpec(Doc)) : undefined) || - Cast(this.props.document[field], listSpec(Doc))) as Doc[]; + return ((this.props.dataDoc ? DocListCast(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field + (layout ? Cast(layout[field], listSpec(Doc)) : undefined) || // else if there's a layout doc, display it's fields + Cast(this.props.document[field], listSpec(Doc))) as Doc[]; // otherwise use the document's data field } @computed get childDocs() { return this.childDocList(this.fieldKey); } @computed get childLinks() { return this.childDocList("links"); } - @computed get templateDataDoc() { - if (this.props.dataDoc === undefined && Doc.LayoutField(this.props.document) !== "string") { - // if there is no dataDoc (ie, we're not rendering a template layout), but this document has a layout document (not a layout string), - // then we render the layout document as a template and use this document as the data context for the template layout. - return this.props.document; - } - return this.props.dataDoc; - } @computed get boundsOfCollectionDocument() { return StrCast(this.props.document.type).indexOf(DocumentType.COL) === -1 || !DocListCast(this.props.document[this.fieldKey]).length ? undefined : Doc.ComputeContentBounds(DocListCast(this.props.document[this.fieldKey])); } - @undoBatch delete = () => this.props.deleteDoc(this.props.document); - @undoBatch openRight = () => this.props.addDocTab(this.props.dropAction === "alias" ? Doc.MakeAlias(this.props.document) : this.props.document, "onRight", this.props.libraryPath); - @undoBatch indent = () => this.props.addDocument(this.props.document) && this.delete(); - @undoBatch move = (doc: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => { + @undoBatch openRight = () => this.props.addDocTab(this.props.document, "onRight", this.props.libraryPath); + @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { return this.props.document !== target && this.props.deleteDoc(doc) && addDoc(doc); } - @undoBatch @action remove = (document: Document, key: string) => { - return Doc.RemoveDocFromList(this.dataDoc, key, document); + @undoBatch @action remove = (doc: Doc | Doc[], key: string) => { + return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => + flg && Doc.RemoveDocFromList(this.dataDoc, key, doc), true); } - @undoBatch @action removeDoc = (document: Document) => { - return Doc.RemoveDocFromList(this.props.containingCollection, Doc.LayoutFieldKey(this.props.containingCollection), document); + @undoBatch @action removeDoc = (doc: Doc | Doc[]) => { + return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => + flg && Doc.RemoveDocFromList(this.props.containingCollection, Doc.LayoutFieldKey(this.props.containingCollection), doc), true); } protected createTreeDropTarget = (ele: HTMLDivElement) => { - this._treedropDisposer && this._treedropDisposer(); + this._treedropDisposer?.(); ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this)), this.props.document); } onPointerEnter = (e: React.PointerEvent): void => { this.props.active(true) && Doc.BrushDoc(this.dataDoc); - if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { + if (e.buttons === 1 && SnappingManager.GetIsDragging()) { this._header!.current!.className = "treeViewItem-header"; document.addEventListener("pointermove", this.onDragMove, true); } @@ -185,7 +166,7 @@ class TreeView extends React.Component<TreeViewProps> { })} OnFillDown={undoBatch((value: string) => { Doc.SetInPlace(this.props.document, key, value, false); - const doc = Docs.Create.FreeformDocument([], { title: "-", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) }); + const doc = Docs.Create.FreeformDocument([], { title: "-", x: 0, y: 0, _width: 100, _height: 25, _LODdisable: true, templates: new List<string>([Templates.Title.Layout]) }); Doc.SetInPlace(this.props.document, "editTitle", undefined, false); Doc.SetInPlace(doc, "editTitle", true, false); return this.props.addDocument(doc); @@ -221,9 +202,10 @@ class TreeView extends React.Component<TreeViewProps> { if (de.complete.docDragData) { e.stopPropagation(); if (de.complete.docDragData.draggedDocuments[0] === this.props.document) return true; - let addDoc = (doc: Doc) => this.props.addDocument(doc, undefined, before); + let addDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, before); if (inside) { - addDoc = (doc: Doc) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) || addDoc(doc); + addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce( + ((flg: boolean, doc) => flg && Doc.AddDocToList(this.dataDoc, this.fieldKey, doc)), true) || addDoc(doc); } const movedDocs = (de.complete.docDragData.treeViewId === this.props.treeViewId[Id] ? de.complete.docDragData.draggedDocuments : de.complete.docDragData.droppedDocuments); const move = de.complete.docDragData.dropAction === "move" || de.complete.docDragData.dropAction; @@ -283,8 +265,9 @@ class TreeView extends React.Component<TreeViewProps> { let contentElement: (JSX.Element | null)[] | JSX.Element = []; if (contents instanceof Doc || (Cast(contents, listSpec(Doc)) && (Cast(contents, listSpec(Doc))!.length && Cast(contents, listSpec(Doc))![0] instanceof Doc))) { - const remDoc = (doc: Doc) => this.remove(doc, key); - const addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true); + const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key); + const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce( + (flg, doc) => flg && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true), true); contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] : DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, @@ -324,10 +307,12 @@ class TreeView extends React.Component<TreeViewProps> { rtfHeight = () => this.rtfWidth() < Doc.Layout(this.props.document)?.[WidthSym]() ? Math.min(Doc.Layout(this.props.document)?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT; @computed get renderContent() { + TraceMobx(); const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined; if (expandKey !== undefined) { - const remDoc = (doc: Doc) => this.remove(doc, expandKey); - const addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, false, true); + const remDoc = (doc: Doc | Doc[]) => this.remove(doc, expandKey); + const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => + (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, false, true), true); const docs = expandKey === "links" ? this.childLinks : this.childDocs; const sortKey = `${this.fieldKey}-sortAscending`; return <ul key={expandKey + "more"} onClick={(e) => { @@ -336,7 +321,7 @@ class TreeView extends React.Component<TreeViewProps> { }}> {!docs ? (null) : TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document), - this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, + this.dataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, StrCast(this.props.document.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath, this.props.onCheckedClick, this.props.onChildClick, this.props.ignoreFields)} @@ -352,7 +337,7 @@ class TreeView extends React.Component<TreeViewProps> { return <div ref={this._dref} style={{ display: "inline-block", height: panelHeight() }} key={this.props.document[Id] + this.props.document.title}> <ContentFittingDocumentView Document={layoutDoc} - DataDoc={this.templateDataDoc} + DataDoc={this.dataDoc} LibraryPath={emptyPath} renderDepth={this.props.renderDepth + 1} rootSelected={returnTrue} @@ -402,13 +387,16 @@ class TreeView extends React.Component<TreeViewProps> { @computed get renderBullet() { const checked = this.props.document.type === DocumentType.COL ? undefined : this.onCheckedClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined; - return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "inherit"), opacity: checked === "unchecked" ? undefined : 0.4 }}> + return <div className="bullet" + title={this.childDocs?.length ? `click to see ${this.childDocs?.length} items` : "view fields"} + onClick={this.bulletClick} + style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "inherit"), opacity: checked === "unchecked" ? undefined : 0.4 }}> {<FontAwesomeIcon icon={checked === "check" ? "check" : (checked === "x" ? "times" : checked === "unchecked" ? "square" : !this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down"))} />} </div>; } showContextMenu = (e: React.MouseEvent) => { - simulateMouseClick(this._docRef.current!.ContentDiv!, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); + this._docRef.current?.ContentDiv && simulateMouseClick(this._docRef.current.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); e.stopPropagation(); } focusOnDoc = (doc: Doc) => DocumentManager.Instance.getFirstDocumentView(doc)?.props.focus(doc, true); @@ -416,15 +404,13 @@ class TreeView extends React.Component<TreeViewProps> { const focusScript = ScriptField.MakeFunction(`DocFocus(self)`); return [{ script: focusScript!, label: "Focus" }]; } - _docRef = React.createRef<DocumentView>(); /** * Renders the EditableView title element for placement into the tree. */ @computed get renderTitle() { - const onItemDown = SetupDrag(this._tref, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId[Id], true); - const editTitle = ScriptField.MakeFunction("setInPlace(this, 'editTitle', true)"); - + TraceMobx(); + (!TreeView._editTitleScript) && (TreeView._editTitleScript = ScriptField.MakeFunction("setInPlace(self, 'editTitle', true)")); const headerElements = ( <> <FontAwesomeIcon icon="cog" size="sm" onClick={e => this.showContextMenu(e)}></FontAwesomeIcon> @@ -445,13 +431,12 @@ class TreeView extends React.Component<TreeViewProps> { <FontAwesomeIcon title="open in pane on right" icon="angle-right" size="lg" /> </div>); return <> - <div className="docContainer" ref={this._tref} title="click to edit title" id={`docContainer-${this.props.parentKey}`} onPointerDown={onItemDown} + <div className="docContainer" ref={this._tref} title="click to edit title" id={`docContainer-${this.props.parentKey}`} style={{ - background: Doc.IsHighlighted(this.props.document) ? "orange" : Doc.IsBrushed(this.props.document) ? "#06121212" : "0", fontWeight: this.props.document.searchMatch ? "bold" : undefined, textDecoration: Doc.GetT(this.props.document, "title", "string", true) ? "underline" : undefined, outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined, - pointerEvents: this.props.active() || DragManager.Vals.Instance.GetIsDragging() ? undefined : "none" + pointerEvents: this.props.active() || SnappingManager.GetIsDragging() ? undefined : "none" }} > {Doc.GetT(this.props.document, "editTitle", "boolean", true) ? this.editableView("title") : @@ -459,12 +444,13 @@ class TreeView extends React.Component<TreeViewProps> { ref={this._docRef} Document={this.props.document} DataDoc={undefined} - LibraryPath={this.props.libraryPath || []} + treeViewId={this.props.treeViewId[Id]} + LibraryPath={this.props.libraryPath || emptyPath} addDocument={undefined} addDocTab={this.props.addDocTab} rootSelected={returnTrue} pinToPres={emptyFunction} - onClick={this.props.onChildClick || editTitle} + onClick={this.props.onChildClick || TreeView._editTitleScript} dropAction={this.props.dropAction} moveDocument={this.move} removeDocument={this.removeDoc} @@ -476,7 +462,7 @@ class TreeView extends React.Component<TreeViewProps> { NativeWidth={returnZero} contextMenuItems={this.contextMenuItems} renderDepth={1} - focus={emptyFunction} + focus={returnTrue} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -491,8 +477,9 @@ class TreeView extends React.Component<TreeViewProps> { } render() { + TraceMobx(); const sorting = this.props.document[`${this.fieldKey}-sortAscending`]; - setTimeout(() => runInAction(() => untracked(() => this._overrideTreeViewOpen = this.treeViewOpen)), 0); + //setTimeout(() => runInAction(() => untracked(() => this._overrideTreeViewOpen = this.treeViewOpen)), 0); return <div className="treeViewItem-container" ref={this.createTreeDropTarget}> <li className="collection-child"> <div className="treeViewItem-header" ref={this._header} onClick={e => { @@ -500,12 +487,14 @@ class TreeView extends React.Component<TreeViewProps> { e.stopPropagation(); e.preventDefault(); } - }} onPointerDown={e => { - if (this.props.active(true)) { - e.stopPropagation(); - e.preventDefault(); - } - }} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> + }} + onPointerDown={e => { + if (this.props.active(true)) { + e.stopPropagation(); + e.preventDefault(); + } + }} + onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> {this.renderBullet} {this.renderTitle} </div> @@ -523,8 +512,8 @@ class TreeView extends React.Component<TreeViewProps> { key: string, parentCollectionDoc: Doc | undefined, parentPrevSibling: Doc | undefined, - add: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean, - remove: ((doc: Doc) => boolean), + add: (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => boolean, + remove: ((doc: Doc | Doc[]) => boolean), move: DragManager.MoveFunction, dropAction: dropActionType, addDocTab: (doc: Doc, where: string) => boolean, @@ -613,7 +602,7 @@ class TreeView extends React.Component<TreeViewProps> { remove(child); } }; - const addDocument = (doc: Doc, relativeTo?: Doc, before?: boolean) => { + const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => { return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false); }; const childLayout = Doc.Layout(pair.layout); @@ -683,22 +672,26 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll } @action - remove = (document: Document): boolean => { - const children = Cast(this.props.Document[DataSym][this.props.fieldKey], listSpec(Doc), []); - if (children.indexOf(document) !== -1) { - children.splice(children.indexOf(document), 1); + remove = (doc: Doc | Doc[]): boolean => { + const docs = doc instanceof Doc ? [doc] : doc; + const targetDataDoc = this.props.Document[DataSym]; + const value = DocListCast(targetDataDoc[this.props.fieldKey]); + const result = value.filter(v => !docs.includes(v)); + if (result.length !== value.length) { + targetDataDoc[this.props.fieldKey] = new List<Doc>(result); return true; } return false; } @action - addDoc = (doc: Document, relativeTo: Opt<Doc>, before?: boolean): boolean => { - const doAddDoc = () => - Doc.AddDocToList(this.props.Document[DataSym], this.props.fieldKey, doc, relativeTo, before, false, false, false); + addDoc = (doc: Doc | Doc[], relativeTo: Opt<Doc>, before?: boolean): boolean => { + const doAddDoc = (doc: Doc | Doc[]) => + (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => + flg && Doc.AddDocToList(this.props.Document[DataSym], this.props.fieldKey, doc, relativeTo, before, false, false, false), true); if (this.props.Document.resolvedDataDoc instanceof Promise) { - this.props.Document.resolvedDataDoc.then((resolved: any) => doAddDoc()); + this.props.Document.resolvedDataDoc.then((resolved: any) => doAddDoc(doc)); } else { - doAddDoc(); + doAddDoc(doc); } return true; } @@ -742,9 +735,16 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll Doc.GetProto(img).doubleClickView = doubleClickView; } }); + Doc.GetProto(d).type = "buxton"; Doc.GetProto(d).proto = heroView; // all devices "are" heroViews that share the same layout & defaults. Seems better than making them all be independent and copy a layout string // .layout = ImageBox.LayoutString("hero"); }); + const iconBuxtonView = ImageDocument(fallbackImg, { title: "hero", _width: 60, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)") }); + iconBuxtonView.isTemplateDoc = makeTemplate(iconBuxtonView, true, "icon_buxton"); + Doc.UserDoc()["template-icon-view-buxton"] = new PrefetchProxy(iconBuxtonView); + const tempIcons = Doc.GetProto(Cast(Doc.UserDoc()["template-icons"], Doc, null)); + Doc.AddDocToList(tempIcons, "data", iconBuxtonView); + Document.childLayoutTemplate = heroView; Document.childClickedOpenTemplateView = new PrefetchProxy(detailView); Document._viewType = CollectionViewType.Time; @@ -767,16 +767,19 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll return <div id="toolbar" key="toolbar"> <button className="toolbar-button round-button" title="Empty" onClick={undoBatch(action(() => Doc.GetProto(this.props.Document)[this.props.fieldKey] = undefined))}> - <FontAwesomeIcon icon={faTrash} size="sm" /> + <FontAwesomeIcon icon={"trash"} size="sm" /> </button> </div >; } + onKeyPress = (e: React.KeyboardEvent) => { + console.log(e); + } render() { if (!(this.props.Document instanceof Doc)) return (null); const dropAction = StrCast(this.props.Document.childDropAction) as dropActionType; - const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before); - const moveDoc = (d: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); + const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before); + const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(d, target, addDoc); const childDocs = this.props.overrideDocuments ? this.props.overrideDocuments : this.childDocs; return !childDocs ? (null) : ( <div className="collectionTreeView-dropTarget" id="body" @@ -786,6 +789,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll paddingRight: `${NumCast(this.props.Document._xPadding, 10)}px`, paddingTop: `${NumCast(this.props.Document._yPadding, 20)}px` }} + onKeyPress={this.onKeyPress} onContextMenu={this.onContextMenu} onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} @@ -800,7 +804,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll SetValue={undoBatch((value: string) => Doc.SetInPlace(this.dataDoc, "title", value, false) || true)} OnFillDown={undoBatch((value: string) => { Doc.SetInPlace(this.dataDoc, "title", value, false); - const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) }); + const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, _LODdisable: true, templates: new List<string>([Templates.Title.Layout]) }); EditableView.loadId = doc[Id]; Doc.SetInPlace(doc, "editTitle", true, false); this.addDoc(doc, childDocs.length ? childDocs[0] : undefined, true); |