From 3dea269077151542bc2450bccd749ede87681556 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 8 Jun 2020 14:18:11 -0400 Subject: a bunch of cleanup to fix import order and to organize/restructure ink things in the right places. --- src/client/views/collections/CollectionTreeView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionTreeView.tsx') diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index b2e1c0f73..e891c4274 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -757,7 +757,7 @@ export class CollectionTreeView extends CollectionSubView UndoManager.RunInBatch(() => Doc.makeCustomViewClicked(this.props.Document, undefined, "onCheckedClick"), "edit onCheckedClick"), icon: "edit" + description: "Edit onChecked Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onCheckedClick"), "edit onCheckedClick"), icon: "edit" }); !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); } -- cgit v1.2.3-70-g09d2 From 5b9d33920858a42319e84eab2c515919feba45ac Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 14 Jun 2020 14:47:57 -0400 Subject: fixed dragging in tree views for Catalog to "copy" documents within the sidebar instead of aliasing them. --- src/client/util/DragManager.ts | 33 +++++++++-------- .../CollectionSchemaMovableTableHOC.tsx | 8 +++-- .../views/collections/CollectionSchemaView.tsx | 4 ++- .../views/collections/CollectionTreeView.tsx | 41 +++++++++++++--------- .../views/collections/CollectionViewChromes.tsx | 5 +-- src/client/views/nodes/DocHolderBox.tsx | 9 +++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 9 ++--- src/mobile/MobileInkOverlay.tsx | 3 +- 8 files changed, 65 insertions(+), 47 deletions(-) (limited to 'src/client/views/collections/CollectionTreeView.tsx') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index cb899ef92..06907d25d 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -13,7 +13,7 @@ import * as globalCssVariables from "../views/globalCssVariables.scss"; import { UndoManager } from "./UndoManager"; import { SnappingManager } from "./SnappingManager"; -export type dropActionType = "alias" | "copy" | "move" | undefined; // undefined = move +export type dropActionType = "alias" | "copy" | "move" | "same" | undefined; // undefined = move export function SetupDrag( _reference: React.RefObject, docFunc: () => Doc | Promise | undefined, @@ -122,7 +122,7 @@ export namespace DragManager { export class DocumentDragData { constructor(dragDoc: Doc[]) { this.draggedDocuments = dragDoc; - this.droppedDocuments = dragDoc; + this.droppedDocuments = []; this.offset = [0, 0]; } draggedDocuments: Doc[]; @@ -209,15 +209,19 @@ export namespace DragManager { }; const batch = UndoManager.StartBatch("dragging"); const finishDrag = (e: DragCompleteEvent) => { - e.docDragData && (e.docDragData.droppedDocuments = - dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : - dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) : - dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeDelegate(d) : d) - ); - e.docDragData?.droppedDocuments.forEach((drop: Doc, i: number) => - (dragData?.removeDropProperties || []).concat(Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), [])).map(prop => drop[prop] = undefined) - ); - batch.end(); + const docDragData = e.docDragData; + if (docDragData && !docDragData.droppedDocuments.length) { + docDragData.dropAction = dragData.userDropAction || dragData.dropAction; + docDragData.droppedDocuments = + dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : + docDragData.dropAction === "alias" ? Doc.MakeAlias(d) : + docDragData.dropAction === "copy" ? Doc.MakeDelegate(d) : d); + docDragData.dropAction !== "same" && docDragData.droppedDocuments.forEach((drop: Doc, i: number) => + (dragData?.removeDropProperties || []).concat(Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), [])).map(prop => drop[prop] = undefined) + ); + batch.end(); + } + return e; }; dragData.draggedDocuments.map(d => d.dragFactory); // does this help? trying to make sure the dragFactory Doc is loaded StartDrag(eles, dragData, downX, downY, options, finishDrag); @@ -231,6 +235,7 @@ export namespace DragManager { initialize?.(bd); Doc.GetProto(bd)["onClick-paramFieldKeys"] = new List(params); e.docDragData && (e.docDragData.droppedDocuments = [bd]); + return e; }; StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag); } @@ -406,14 +411,13 @@ export namespace DragManager { const yFromTop = downY - elesCont.top; const xFromRight = elesCont.right - downX; const yFromBottom = elesCont.bottom - downY; - let alias = "alias"; const moveHandler = (e: PointerEvent) => { e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : undefined; } - if (e?.shiftKey && dragData.droppedDocuments.length === 1) { - !dragData.dropAction && (dragData.dropAction = alias); + if (e?.shiftKey && dragData.draggedDocuments.length === 1) { + dragData.dropAction = dragData.userDropAction || "same"; if (dragData.dropAction === "move") { dragData.removeDocument?.(dragData.draggedDocuments[0]); } @@ -429,7 +433,6 @@ export namespace DragManager { const { thisX, thisY } = snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom); - alias = "move"; const moveX = thisX - lastX; const moveY = thisY - lastY; lastX = thisX; diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 6f1e8ac1f..6588825ba 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -66,8 +66,9 @@ export class MovableColumn extends React.Component { const rect = this._header!.current!.getBoundingClientRect(); const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); const before = x[0] < bounds[0]; - if (de.complete.columnDragData) { - this.props.reorderColumns(de.complete.columnDragData.colKey, this.props.columnValue, before, this.props.allColumns); + const colDragData = de.complete.columnDragData; + if (colDragData) { + this.props.reorderColumns(colDragData.colKey, this.props.columnValue, before, this.props.allColumns); return true; } return false; @@ -164,13 +165,14 @@ export class MovableRow extends React.Component { } createRowDropTarget = (ele: HTMLDivElement) => { - this._rowDropDisposer && this._rowDropDisposer(); + this._rowDropDisposer?.(); if (ele) { this._rowDropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this)); } } rowDrop = (e: Event, de: DragManager.DropEvent) => { + this.onPointerLeave(e as any); const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc)); if (!rowDoc) return false; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 89fc6a406..252fa547e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -29,6 +29,7 @@ import { CollectionView } from "./CollectionView"; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; import { setupMoveUpEvents, emptyFunction, returnZero, returnOne, returnFalse } from "../../../Utils"; import { DocumentView } from "../nodes/DocumentView"; +import { SnappingManager } from "../../util/SnappingManager"; library.add(faCog, faPlus, faSortUp, faSortDown); library.add(faTable); @@ -186,7 +187,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } render() { - return
+ return
this.props.active(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} ref={this.createTarget}> {this.schemaTable}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index e891c4274..8f30e71b6 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -123,7 +123,7 @@ class TreeView extends React.Component { protected createTreeDropTarget = (ele: HTMLDivElement) => { this._treedropDisposer?.(); - ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this)), this.props.document); + ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.props.document); } onPointerEnter = (e: React.PointerEvent): void => { @@ -187,33 +187,36 @@ class TreeView extends React.Component { })} />) + preTreeDrop = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => { + const dragData = de.complete.docDragData; + dragData && (dragData.dropAction = this.props.treeViewId[Id] === dragData.treeViewId ? "same" : dragData.dropAction); + } + @undoBatch treeDrop = (e: Event, de: DragManager.DropEvent) => { const pt = [de.x, de.y]; const rect = this._header!.current!.getBoundingClientRect(); const before = pt[1] < rect.top + rect.height / 2; const inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length); - if (de.complete.linkDragData) { - const sourceDoc = de.complete.linkDragData.linkSourceDocument; + const complete = de.complete; + if (complete.linkDragData) { + const sourceDoc = complete.linkDragData.linkSourceDocument; const destDoc = this.props.document; DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc }, "tree link"); e.stopPropagation(); } - if (de.complete.docDragData) { + const docDragData = complete.docDragData; + if (docDragData) { e.stopPropagation(); - if (de.complete.docDragData.draggedDocuments[0] === this.props.document) return true; - let addDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, before); + if (docDragData.draggedDocuments[0] === this.props.document) return true; + const parentAddDoc = (doc: Doc | Doc[]) => this.props.addDocument(doc, undefined, before); + let addDoc = parentAddDoc; if (inside) { addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce( - ((flg: boolean, doc) => flg && Doc.AddDocToList(this.dataDoc, this.fieldKey, doc)), true) || addDoc(doc); + (flg: boolean, doc) => flg && Doc.AddDocToList(this.dataDoc, this.fieldKey, doc), true) || parentAddDoc(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; - return ((!move && (de.complete.docDragData.treeViewId !== this.props.treeViewId[Id])) || de.complete.docDragData.userDropAction) ? - de.complete.docDragData.droppedDocuments.reduce((added, d) => addDoc(d) || added, false) - : de.complete.docDragData.moveDocument ? - movedDocs.reduce((added, d) => de.complete.docDragData?.moveDocument?.(d, undefined, addDoc) || added, false) - : de.complete.docDragData.droppedDocuments.reduce((added, d) => addDoc(d), false); + const move = (!docDragData.dropAction || docDragData.dropAction === "move" || docDragData.dropAction === "same") && docDragData.moveDocument; + return docDragData.droppedDocuments.reduce((added, d) => (move ? docDragData.moveDocument?.(d, undefined, addDoc) : addDoc(d)) || added, false); } return false; } @@ -662,10 +665,15 @@ export class CollectionTreeView extends CollectionSubView { this.treedropDisposer?.(); if (this._mainEle = ele) { - this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.props.Document); + this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.props.Document, this.onInternalPreDrop.bind(this)); } } + protected onInternalPreDrop = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => { + const dragData = de.complete.docDragData; + dragData && (dragData.dropAction = this.props.Document[Id] === dragData?.treeViewId ? "same" : dragData.dropAction); + } + componentWillUnmount() { super.componentWillUnmount(); this.treedropDisposer?.(); @@ -788,7 +796,8 @@ export class CollectionTreeView extends CollectionSubView c.title === this._currentKey).map(c => c.immediate(de.complete.docDragData?.draggedDocuments || [])); + const docDragData = de.complete.docDragData; + if (docDragData?.draggedDocuments.length) { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || [])); e.stopPropagation(); } return true; diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx index 0c5239d66..a4c4663dd 100644 --- a/src/client/views/nodes/DocHolderBox.tsx +++ b/src/client/views/nodes/DocHolderBox.tsx @@ -198,11 +198,10 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent { - if (de.complete.docDragData) { - if (de.complete.docDragData.draggedDocuments[0].type === DocumentType.FONTICON) { - const doc = Cast(de.complete.docDragData.draggedDocuments[0].dragFactory, Doc, null); - this.layoutDoc.childLayoutTemplate = doc; - } + const docDragData = de.complete.docDragData; + if (docDragData?.draggedDocuments[0].type === DocumentType.FONTICON) { + const doc = Cast(docDragData.draggedDocuments[0].dragFactory, Doc, null); + this.layoutDoc.childLayoutTemplate = doc; } } protected createDropTarget = (ele: HTMLDivElement) => { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index ffab1d1e1..fc5ab50d9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -283,8 +283,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { - if (de.complete.docDragData) { - const draggedDoc = de.complete.docDragData.draggedDocuments.length && de.complete.docDragData.draggedDocuments[0]; + const dragData = de.complete.docDragData; + if (dragData) { + const draggedDoc = dragData.draggedDocuments.length && dragData.draggedDocuments[0]; // replace text contents whend dragging with Alt if (draggedDoc && draggedDoc.type === DocumentType.RTF && !Doc.AreProtosEqual(draggedDoc, this.props.Document) && de.altKey) { if (draggedDoc.data instanceof RichTextField) { @@ -292,8 +293,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp e.stopPropagation(); } // embed document when dragging with a userDropAction or an embedDoc flag set - } else if (de.complete.docDragData.userDropAction || de.complete.docDragData.embedDoc) { - const target = de.complete.docDragData.droppedDocuments[0]; + } else if (dragData.userDropAction || dragData.embedDoc) { + const target = dragData.droppedDocuments[0]; // const link = DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "Embedded Doc:" + target.title); // if (link) { target._fitToBox = true; diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx index 973931615..59c73ed27 100644 --- a/src/mobile/MobileInkOverlay.tsx +++ b/src/mobile/MobileInkOverlay.tsx @@ -114,7 +114,8 @@ export default class MobileInkOverlay extends React.Component { altKey: false, metaKey: false, ctrlKey: false, - shiftKey: false + shiftKey: false, + embedKey: false } } ) -- cgit v1.2.3-70-g09d2 From 39d2e4a2e70ace7a882d3b3b9d9cf06b4224fa69 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 14 Jun 2020 23:14:20 -0400 Subject: changed library to have catalog default to a schema view. fixed dragging to/from catalog to use 'same' and 'alias' as appropriate for dragging in/out. --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 10 ++++++---- src/client/util/DragManager.ts | 2 +- .../views/collections/CollectionSchemaMovableTableHOC.tsx | 5 +---- src/client/views/collections/CollectionSchemaView.tsx | 6 ++++-- src/client/views/collections/CollectionTreeView.tsx | 6 +++++- src/fields/Doc.ts | 3 ++- 7 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src/client/views/collections/CollectionTreeView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8d867348f..2ecc8c8b7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -696,7 +696,7 @@ export namespace Docs { } export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List(schemaColumns), ...options, _viewType: CollectionViewType.Schema }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List(schemaColumns.length ? schemaColumns : [new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Schema }); } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index b0cea9947..0acfb72c6 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -510,8 +510,9 @@ export class CurrentUserUtils { } static setupCatalog(doc: Doc) { if (doc.myCatalog === undefined) { - doc.myCatalog = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "CATALOG", _height: 42, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, lockedPosition: true, + doc.myCatalog = new PrefetchProxy(Docs.Create.SchemaDocument([], [], { + title: "CATALOG", _height: 1000, _fitWidth: true, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, lockedPosition: true, + childDropAction: "alias", targetDropAction: "same", treeViewExpandedView: "layout" })); } return doc.myCatalog as Doc; @@ -539,10 +540,11 @@ export class CurrentUserUtils { if (doc["tabs-button-library"] === undefined) { doc["tabs-button-library"] = new PrefetchProxy(Docs.Create.ButtonDocument({ - _width: 50, _height: 25, title: "Library", _fontSize: 10, + _width: 50, _height: 25, title: "Library", _fontSize: 10, targetDropAction: "same", letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: new PrefetchProxy(Docs.Create.TreeDocument([workspaces, documents, recentlyClosed, doc], { - title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true + title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", + lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same" })) as any as Doc, targetContainer: new PrefetchProxy(sidebarContainer) as any as Doc, onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel;") diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 06907d25d..597b72e0c 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -37,7 +37,7 @@ export function SetupDrag( dragData.treeViewId = treeViewId; dragData.dontHideOnDrop = dontHideOnDrop; DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y); - dragStarted && dragStarted(); + dragStarted?.(); } }; const onRowUp = (): void => { diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 6588825ba..b206765e8 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -205,10 +205,7 @@ export class MovableRow extends React.Component { @action move: DragManager.MoveFunction = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc) => { const targetView = targetCollection && DocumentManager.Instance.getDocumentView(targetCollection); - if (targetView && targetView.props.ContainingCollectionDoc) { - return doc !== targetCollection && doc !== targetView.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc); - } - return doc !== targetCollection && this.props.removeDoc(doc) && addDoc(doc); + return doc !== targetCollection && doc !== targetView?.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc); } render() { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 252fa547e..6dbee217a 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -28,7 +28,6 @@ import { CollectionSubView } from "./CollectionSubView"; import { CollectionView } from "./CollectionView"; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; import { setupMoveUpEvents, emptyFunction, returnZero, returnOne, returnFalse } from "../../../Utils"; -import { DocumentView } from "../nodes/DocumentView"; import { SnappingManager } from "../../util/SnappingManager"; library.add(faCog, faPlus, faSortUp, faSortDown); @@ -188,7 +187,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { render() { return
+ style={{ + pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined, + width: this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%" + }} >
this.props.active(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} ref={this.createTarget}> {this.schemaTable}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 8f30e71b6..180bcdd02 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -671,7 +671,11 @@ export class CollectionTreeView extends CollectionSubView { const dragData = de.complete.docDragData; - dragData && (dragData.dropAction = this.props.Document[Id] === dragData?.treeViewId ? "same" : dragData.dropAction); + if (dragData) { + if (targetAction && !dragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) { + dragData.dropAction = targetAction; + } else dragData.dropAction = this.props.Document[Id] === dragData?.treeViewId ? "same" : dragData.dropAction; + } } componentWillUnmount() { diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index ffef9a384..a72088d04 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -442,7 +442,8 @@ export namespace Doc { if (allowDuplicates !== true) { const pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1); if (pind !== -1) { - list.splice(pind, 1); + return true; + //list.splice(pind, 1); // bcz: this causes schemaView docs in the Catalog to move to the bottom of the schema view when they are dragged even though they haven't left the collection } } if (first) { -- cgit v1.2.3-70-g09d2 From 3927564a9ff22af07490f0e98be3e8cbe1a4d3ab Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 16 Jun 2020 23:24:30 -0400 Subject: changed Doc.MakeCopy() to ignore layout[ fields so that copying text documents with a layout doesn't copy their text --- src/client/util/SettingsManager.tsx | 7 +++- .../views/collections/CollectionTreeView.tsx | 7 ++-- src/client/views/collections/CollectionView.tsx | 10 +++-- src/client/views/nodes/DocumentView.tsx | 46 +++++++++++----------- src/client/views/nodes/ImageBox.tsx | 5 --- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- .../formattedText/ProsemirrorExampleTransfer.ts | 4 +- src/fields/Doc.ts | 2 +- 8 files changed, 45 insertions(+), 38 deletions(-) (limited to 'src/client/views/collections/CollectionTreeView.tsx') diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 0e15197c4..9888cce48 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -10,6 +10,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Networking } from "../Network"; import { CurrentUserUtils } from "./CurrentUserUtils"; import { Utils } from "../../Utils"; +import { Doc } from "../../fields/Doc"; library.add(fa.faWindowClose); @@ -78,6 +79,10 @@ export default class SettingsManager extends React.Component<{}> { this.errorText = ""; this.successText = ""; } + @action + noviceToggle = (event: any) => { + Doc.UserDoc().noviceMode = !Doc.UserDoc().noviceMode; + } private get settingsInterface() { return ( @@ -91,7 +96,7 @@ export default class SettingsManager extends React.Component<{}> {
- + diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 180bcdd02..d631a492e 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -83,8 +83,9 @@ class TreeView extends React.Component { private _tref = React.createRef(); private _docRef = React.createRef(); + get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); } 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"); } + get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, this.noviceMode ? "layout" : "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 && !this.props.document.treeViewPreventOpen && BoolCast(this.props.document.treeViewOpen)) || this._overrideTreeViewOpen; } @@ -420,10 +421,10 @@ class TreeView extends React.Component { { if (this.treeViewOpen) { - this.props.document.treeViewExpandedView = this.treeViewExpandedView === this.fieldKey ? "fields" : + this.props.document.treeViewExpandedView = this.treeViewExpandedView === this.fieldKey ? (Doc.UserDoc().noviceMode ? "layout" : "fields") : this.treeViewExpandedView === "fields" && Doc.Layout(this.props.document) ? "layout" : this.treeViewExpandedView === "layout" && this.props.document.links ? "links" : - this.childDocs ? this.fieldKey : "fields"; + this.childDocs ? this.fieldKey : (Doc.UserDoc().noviceMode ? "layout" : "fields"); } this.treeViewOpen = true; })}> diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 215b5bce8..e436a13ab 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -282,10 +282,12 @@ export class CollectionView extends Touchable ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); - !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + if (!Doc.UserDoc().noviceMode) { + const more = ContextMenu.Instance.findByDescription("More..."); + const moreItems = more && "subitems" in more ? more.subitems : []; + moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); + !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + } } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index da5327f48..e7cfb5e9c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -759,30 +759,32 @@ export class DocumentView extends DocComponent(Docu } const more = cm.findByDescription("More..."); - const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : []; - moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); - moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); + const moreItems = more && "subitems" in more ? more.subitems : []; + if (!Doc.UserDoc().noviceMode) { + moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); + moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); + + if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { + moreItems.push({ description: "Export to Google Photos Album", event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.props.Document }).then(console.log), icon: "caret-square-right" }); + moreItems.push({ description: "Tag Child Images via Google Photos", event: () => GooglePhotos.Query.TagChildImages(this.props.Document), icon: "caret-square-right" }); + moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" }); + } + moreItems.push({ + description: "Download document", icon: "download", event: async () => { + const response = await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), { + qs: { q: 'world', fq: 'NOT baseProto_b:true AND NOT deleted:true', start: '0', rows: '100', hl: true, 'hl.fl': '*' } + }); + console.log(response ? JSON.parse(response) : undefined); + } + // const a = document.createElement("a"); + // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`); + // a.href = url; + // a.download = `DocExport-${this.props.Document[Id]}.zip`; + // a.click(); + }); + } moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); - - if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { - moreItems.push({ description: "Export to Google Photos Album", event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.props.Document }).then(console.log), icon: "caret-square-right" }); - moreItems.push({ description: "Tag Child Images via Google Photos", event: () => GooglePhotos.Query.TagChildImages(this.props.Document), icon: "caret-square-right" }); - moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" }); - } - moreItems.push({ - description: "Download document", icon: "download", event: async () => { - const response = await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), { - qs: { q: 'world', fq: 'NOT baseProto_b:true AND NOT deleted:true', start: '0', rows: '100', hl: true, 'hl.fl': '*' } - }); - console.log(response ? JSON.parse(response) : undefined); - } - // const a = document.createElement("a"); - // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`); - // a.href = url; - // a.download = `DocExport-${this.props.Document[Id]}.zip`; - // a.click(); - }); moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" }); !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index cabf30c13..69cffb6c2 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -182,11 +182,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), "change view"), icon: "eye" }); + changeItems.push({ description: "FreeForm", event: () => DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), icon: "eye" }); !change && cm.addItem({ description: "Change Perspective...", subitems: changeItems, icon: "external-link-alt" }); } diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 114288a9d..0a4c52ef9 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -7,7 +7,7 @@ import { splitListItem, wrapInList, } from "prosemirror-schema-list"; import { EditorState, Transaction, TextSelection } from "prosemirror-state"; import { SelectionManager } from "../../../util/SelectionManager"; import { NumCast, BoolCast, Cast, StrCast } from "../../../../fields/Types"; -import { Doc } from "../../../../fields/Doc"; +import { Doc, DataSym } from "../../../../fields/Doc"; import { FormattedTextBox } from "./FormattedTextBox"; import { Id } from "../../../../fields/FieldSymbols"; import { Docs } from "../../../documents/Documents"; @@ -142,6 +142,7 @@ export default function buildKeymap>(schema: S, props: any if (force || props.Document._singleLine) { const layoutKey = StrCast(originalDoc.layoutKey); const newDoc = Doc.MakeCopy(originalDoc, true); + newDoc[DataSym][Doc.LayoutFieldKey(newDoc)] = undefined; newDoc.y = NumCast(originalDoc.y) + NumCast(originalDoc._height) + 10; if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) { newDoc[layoutKey] = originalDoc[layoutKey]; @@ -166,6 +167,7 @@ export default function buildKeymap>(schema: S, props: any if (originalDoc instanceof Doc) { const layoutKey = StrCast(originalDoc.layoutKey); const newDoc = Doc.MakeCopy(originalDoc, true); + newDoc[DataSym][Doc.LayoutFieldKey(newDoc)] = undefined; newDoc.x = NumCast(originalDoc.x) + NumCast(originalDoc._width) + 10; if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) { newDoc[layoutKey] = originalDoc[layoutKey]; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 70aa2d60b..96587af44 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -670,7 +670,7 @@ export namespace Doc { copy[key] = cfield[Copy]();// ComputedField.MakeFunction(cfield.script.originalScript); } else if (field instanceof ObjectField) { copy[key] = doc[key] instanceof Doc ? - key.includes("layout[") ? Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields + key.includes("layout[") ? undefined : doc[key] : // reference documents except remove documents that are expanded teplate fields ObjectField.MakeCopy(field); } else if (field instanceof Promise) { debugger; //This shouldn't happend... -- cgit v1.2.3-70-g09d2 From 375786198596ce8dcab06c39c5b4ffcca4a78b88 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 17 Jun 2020 10:59:54 -0400 Subject: fixed move document to undo correctly when ACLs of target don't allow a drop. --- src/client/util/UndoManager.ts | 22 ++++++++++++++++++++-- src/client/views/RecommendationsBox.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 15 +++++++++++++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 -- src/client/views/nodes/DocumentView.tsx | 3 --- 6 files changed, 35 insertions(+), 11 deletions(-) (limited to 'src/client/views/collections/CollectionTreeView.tsx') diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts index 314b52bf3..c7b7bb215 100644 --- a/src/client/util/UndoManager.ts +++ b/src/client/util/UndoManager.ts @@ -78,10 +78,12 @@ export namespace UndoManager { let currentBatch: UndoBatch | undefined; let batchCounter = 0; let undoing = false; + let tempEvents: UndoEvent[] | undefined = undefined; export function AddEvent(event: UndoEvent): void { if (currentBatch && batchCounter && !undoing) { currentBatch.push(event); + tempEvents?.push(event); } } @@ -135,7 +137,7 @@ export namespace UndoManager { const EndBatch = action((cancel: boolean = false) => { batchCounter--; - if (batchCounter === 0 && currentBatch && currentBatch.length) { + if (batchCounter === 0 && currentBatch?.length) { if (!cancel) { undoStack.push(currentBatch); } @@ -144,6 +146,13 @@ export namespace UndoManager { } }); + export function ClearTempBatch() { + tempEvents = undefined; + } + export function RunInTempBatch(fn: () => T) { + tempEvents = []; + return runInAction(fn); + } //TODO Make this return the return value export function RunInBatch(fn: () => T, batchName: string) { const batch = StartBatch(batchName); @@ -153,7 +162,16 @@ export namespace UndoManager { batch.end(); } } - + export const UndoTempBatch = action(() => { + if (tempEvents) { + undoing = true; + for (let i = tempEvents.length - 1; i >= 0; i--) { + tempEvents[i].undo(); + } + undoing = false; + } + tempEvents = undefined; + }); export const Undo = action(() => { if (undoStack.length === 0) { return; diff --git a/src/client/views/RecommendationsBox.tsx b/src/client/views/RecommendationsBox.tsx index 8ca81c070..c98363214 100644 --- a/src/client/views/RecommendationsBox.tsx +++ b/src/client/views/RecommendationsBox.tsx @@ -56,7 +56,7 @@ export class RecommendationsBox extends React.Component { } const returnXDimension = () => 150; const returnYDimension = () => 150; - const scale = () => returnXDimension() / NumCast(renderDoc.nativeWidth, returnXDimension()); + const scale = () => returnXDimension() / NumCast(renderDoc._nativeWidth, returnXDimension()); //let scale = () => 1; const newRenderDoc = Doc.MakeAlias(renderDoc); /// newRenderDoc -> renderDoc -> render"data"Doc -> TextProt newRenderDoc.height = NumCast(this.props.Document.documentIconHeight); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index d631a492e..be0339345 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -250,7 +250,7 @@ class TreeView extends React.Component { const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]()); if (aspect) return this.docWidth() * aspect; if (bounds) return this.docWidth() * (bounds.b - bounds.y) / (bounds.r - bounds.x); - return layoutDoc._fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection._height) : + return layoutDoc._fitWidth ? (!this.props.document._nativeHeight ? NumCast(this.props.containingCollection._height) : Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth, NumCast(this.props.containingCollection._height)))) : NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e436a13ab..be79dbce1 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -45,6 +45,7 @@ import { CollectionTreeView } from "./CollectionTreeView"; import { CollectionGridView } from './collectionGrid/CollectionGridView'; import './CollectionView.scss'; import { CollectionViewBaseChrome } from './CollectionViewChromes'; +import { UndoManager } from '../../util/UndoManager'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -166,7 +167,17 @@ export class CollectionView extends Touchable this.removeDocument(doc))) { + const added = addDocument(doc); + if (!added) UndoManager.UndoTempBatch(); + else UndoManager.ClearTempBatch(); + + return added; + } + UndoManager.ClearTempBatch(); + } + return false; } showIsTagged = () => { @@ -431,7 +442,7 @@ export class CollectionView extends Touchable e.stopPropagation()}> +
fmovede.stopPropagation()}> {this._allFacets.map(facet =>