aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/DocumentDecorations.tsx32
-rw-r--r--src/client/views/GlobalKeyHandler.ts2
-rw-r--r--src/client/views/MainView.scss26
-rw-r--r--src/client/views/MainView.tsx6
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx6
-rw-r--r--src/client/views/collections/CollectionMenu.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx12
-rw-r--r--src/client/views/collections/TabDocView.scss5
-rw-r--r--src/client/views/collections/TabDocView.tsx9
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
-rw-r--r--src/client/views/nodes/FilterBox.tsx6
-rw-r--r--src/client/views/nodes/FontIconBox.tsx10
12 files changed, 82 insertions, 39 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 41be364fd..e4e27bec7 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -13,7 +13,7 @@ import { GetEffectiveAcl } from '../../fields/util';
import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick, returnVal } from "../../Utils";
import { DocUtils, Docs } from "../documents/Documents";
import { DocumentType } from '../documents/DocumentTypes';
-import { DragManager } from "../util/DragManager";
+import { DragManager, dropActionType } from "../util/DragManager";
import { SelectionManager } from "../util/SelectionManager";
import { SnappingManager } from '../util/SnappingManager';
import { undoBatch, UndoManager } from "../util/UndoManager";
@@ -137,8 +137,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
const dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0);
dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top);
- dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument;
+ dragData.moveDocument = dragDocView.props.moveDocument;
dragData.isSelectionMove = true;
+ dragData.dropAction = dragDocView.props.Document.dropAction as dropActionType;
this.Interacting = true;
this._hidden = true;
DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(dv => dv.ContentDiv!), dragData, e.x, e.y, {
@@ -578,20 +579,25 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
return (null);
}
const canDelete = SelectionManager.SelectedDocuments().some(docView => {
- const collectionAcl = GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]);
- return collectionAcl === AclAdmin || collectionAcl === AclEdit;
+ const collectionAcl = docView.props.ContainingCollectionView ? GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]) : AclEdit;
+ return !docView.props.Document._stayInCollection && (collectionAcl === AclAdmin || collectionAcl === AclEdit);
});
- const minimal = bounds.r - bounds.x < 100 ? true : false;
- const closeIcon = canDelete ? (
+ const canOpen = SelectionManager.SelectedDocuments().some(docView => !docView.props.Document._stayInCollection);
+ const closeIcon = !canDelete ? (null) : (
<Tooltip title={<div className="dash-tooltip">Close</div>} placement="top">
<div className="documentDecorations-closeButton" onClick={this.onCloseClick}>
<FontAwesomeIcon className="documentdecorations-times" icon={"times"} size="lg" />
- </div></Tooltip>) : (null);
+ </div></Tooltip>);
+
+ const openIcon = !canOpen ? (null) : <Tooltip title={<div className="dash-tooltip">Open In a New Pane</div>} placement="top"><div className="documentDecorations-openInTab" onContextMenu={e => { e.preventDefault(); e.stopPropagation(); }} onPointerDown={this.onMaximizeDown}>
+ {SelectionManager.SelectedDocuments().length === 1 ? <FontAwesomeIcon icon="external-link-alt" className="documentView-minimizedIcon" /> : "..."}
+ </div>
+ </Tooltip>;
const titleArea = this._edtingTitle ?
<input ref={this._keyinput} className="documentDecorations-title" type="text" name="dynbox" autoComplete="on" value={this._accumulatedTitle}
onBlur={e => this.titleBlur(true)} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} /> :
- <div className="documentDecorations-title" style={{ gridColumnEnd: minimal ? 4 : 5 }} key="title" onPointerDown={this.onTitleDown} >
+ <div className="documentDecorations-title" style={{ gridColumnEnd: 5 }} key="title" onPointerDown={this.onTitleDown} >
<span style={{ width: "100%", display: "inline-block", cursor: "move" }}>{`${this.selectionTitle}`}</span>
</div>;
@@ -627,14 +633,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
}}>
{closeIcon}
{Object.keys(SelectionManager.SelectedDocuments()[0].props).includes("treeViewDoc") ? (null) : titleArea}
- {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK || minimal || Object.keys(SelectionManager.SelectedDocuments()[0].props).includes("treeViewDoc") ? (null) :
+ {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK || Object.keys(SelectionManager.SelectedDocuments()[0].props).includes("treeViewDoc") ? (null) :
<Tooltip title={<div className="dash-tooltip">{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}</div>} placement="top">
<div className="documentDecorations-iconifyButton" onPointerDown={this.onIconifyDown}>
<FontAwesomeIcon icon={seldoc.finalLayoutKey.includes("icon") ? "window-restore" : "window-minimize"} className="documentView-minimizedIcon" />
</div></Tooltip>}
- <Tooltip title={<div className="dash-tooltip">Open In a New Pane</div>} placement="top"><div className="documentDecorations-openInTab" onContextMenu={e => { e.preventDefault(); e.stopPropagation(); }} onPointerDown={this.onMaximizeDown}>
- {SelectionManager.SelectedDocuments().length === 1 ? <FontAwesomeIcon icon="external-link-alt" className="documentView-minimizedIcon" /> : "..."}
- </div></Tooltip>
+ {openIcon}
<div className="documentDecorations-topLeftResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
<div className="documentDecorations-topResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
<div className="documentDecorations-topRightResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
@@ -654,9 +658,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
onPointerDown={useRotation ? this.onRotateDown : this.onRadiusDown} onContextMenu={(e) => e.preventDefault()}>{useRotation && "⟲"}</div>
</div >
- <div className="link-button-container" key="links" style={{ left: bounds.x - this._resizeBorderWidth / 2 + 10, top: bounds.b + this._resizeBorderWidth / 2 }}>
+ {seldoc?.Document.type === DocumentType.FONTICON ? (null) : <div className="link-button-container" key="links" style={{ left: bounds.x - this._resizeBorderWidth / 2 + 10, top: bounds.b + this._resizeBorderWidth / 2 }}>
<DocumentButtonBar views={SelectionManager.SelectedDocuments} />
- </div>
+ </div>}
</>}
</div >
);
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 83c02b09b..b231b2171 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -113,7 +113,7 @@ export class KeyManager {
}
const selected = SelectionManager.SelectedDocuments().slice();
- UndoManager.RunInBatch(() => selected.map(dv => dv.props.removeDocument?.(dv.props.Document)), "delete");
+ UndoManager.RunInBatch(() => selected.map(dv => !dv.props.Document._stayInCollection && dv.props.removeDocument?.(dv.props.Document)), "delete");
SelectionManager.DeselectAll();
break;
case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(-1, 0)), "nudge left"); break;
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index aebb28859..5bab43a3b 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -382,4 +382,30 @@
display: block;
width: 500px;
height: 1000px;
+}
+
+.lm_drag_tab {
+ padding: 0;
+ width: 15px !important;
+ height: 15px !important;
+ position: relative !important;
+ display: inline-flex !important;
+ align-items: center;
+ top: 0 !important;
+ right: unset !important;
+ left: 0 !important;
+}
+.lm_close_tab {
+ padding: 0;
+ width: 15px !important;
+ height: 15px !important;
+ position: relative !important;
+ display: inline-flex !important;
+ align-items: center;
+ top: 0 !important;
+ right: unset !important;
+ left: 0 !important;
+}
+.lm_tab, .lm_tab_active {
+ display: flex !important;
} \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 82261fcf0..c2290dd09 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -445,11 +445,7 @@ export class MainView extends React.Component {
remButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.RemoveDocFromList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
moveButtonDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
- addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => {
- const ret = flg && Doc.AddDocToList(Doc.UserDoc().dockedBtns as Doc, "data", doc);
- ret && (doc._stayInCollection = undefined);
- return ret;
- }, true)
+ addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
buttonBarXf = () => {
if (!this._docBtnRef.current) return Transform.Identity();
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 306b9187e..4685d2ffc 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -152,7 +152,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
const newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
if (instance._goldenLayout.root.contentItems.length === 0) { // if no rows / columns
instance._goldenLayout.root.addChild(newContentItem);
- } else if (instance._goldenLayout.root.contentItems[0].isRow) { // if row
+ } else if (instance._goldenLayout.root.contentItems.length === 1 && instance._goldenLayout.root.contentItems[0].contentItems.length === 1 &&
+ instance._goldenLayout.root.contentItems[0].contentItems[0].contentItems.length === 0) {
+ instance._goldenLayout.root.contentItems[0].contentItems[0].addChild(docContentConfig);
+ }
+ else if (instance._goldenLayout.root.contentItems[0].isRow) { // if row
switch (pullSide) {
default:
case "right": instance._goldenLayout.root.contentItems[0].addChild(newContentItem); break;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 9e67faed5..0f8a5df0d 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -417,7 +417,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
if (this._dragRef.current && this.selectedDoc) {
const dragData = new DragManager.DocumentDragData([this.selectedDoc]);
const [left, top] = [e.clientX, e.clientY];
- dragData.dropAction = "alias";
+ dragData.defaultDropAction = "alias";
DragManager.StartDocumentDrag([this._dragRef.current], dragData, left, top, {
offsetX: dragData.offset[0],
offsetY: dragData.offset[1],
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index ed5414954..dc1d5a8dd 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,5 +1,4 @@
import { action, computed, IReactionDisposer, reaction, observable, runInAction } from "mobx";
-import { basename } from 'path';
import CursorField from "../../../fields/CursorField";
import { Doc, Opt, Field, DocListCast } from "../../../fields/Doc";
import { Id, ToString } from "../../../fields/FieldSymbols";
@@ -220,15 +219,20 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if (docDragData) {
let added = false;
const dropAction = docDragData.dropAction || docDragData.userDropAction;
- if ((!dropAction || dropAction === "move") && docDragData.moveDocument) {
+ const targetDocments = DocListCast(this.dataDoc[this.props.fieldKey]);
+ const someMoved = !docDragData.userDropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag));
+ if (someMoved) docDragData.droppedDocuments = docDragData.droppedDocuments.map((drop, i) => targetDocments.includes(docDragData.draggedDocuments[i]) ? docDragData.draggedDocuments[i] : drop);
+ if ((!dropAction || dropAction === "move" || someMoved) && docDragData.moveDocument) {
const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
- const res = addedDocs.length ? this.addDocument(addedDocs) : true;
if (movedDocs.length) {
const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey || !this.props.isAnnotationOverlay ||
Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.addDocument : returnFalse);
- } else added = res;
+ } else {
+ ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
+ added = addedDocs.length ? this.addDocument(addedDocs) : true;
+ }
added && e.stopPropagation();
return added;
} else {
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index 5dfb9366a..edf556c9f 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -4,10 +4,15 @@ input.lm_title
max-width: unset !important;
transition-delay: unset;
width: 100%;
+ cursor: text;
}
input.lm_title {
transition-delay: 0.35s;
width: 100px;
+ cursor: pointer;
+}
+.tabDocView-drag {
+ margin: auto;
}
.miniMap-hidden,
.miniMap {
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index bd5032536..f89285923 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -91,16 +91,13 @@ export class TabDocView extends React.Component<TabDocViewProps> {
//attach the selection doc buttons menu to the drag handle
const stack = tab.contentItem.parent;
- const dragHdl = document.createElement("span");
- dragHdl.className = "collectionDockingView-gear";
- dragHdl.style.position = "relative";
- dragHdl.style.paddingLeft = "0px";
- dragHdl.style.paddingRight = "12px";
+ const dragHdl = document.createElement("div");
+ dragHdl.className = "lm_drag_tab";
tab._disposers.buttonDisposer = reaction(() => this.view, view =>
view && [ReactDOM.render(<span className="tabDocView-drag" onPointerDown={dragBtnDown}><CollectionDockingViewMenu views={() => [view]} Stack={stack} /></span>, dragHdl), tab._disposers.buttonDisposer?.()],
{ fireImmediately: true });
tab.reactComponents = [dragHdl];
- tab.element.append(dragHdl);
+ tab.closeElement.before(dragHdl);
// highlight the tab when the tab document is brushed in any part of the UI
tab._disposers.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index def9d8554..5ca57a193 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -752,6 +752,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@action
onContextMenu = (e?: React.MouseEvent, pageX?: number, pageY?: number) => {
+ if (e && this.rootDoc._hideContextMenu && Doc.UserDoc().noviceMode) {
+ e.preventDefault();
+ e.stopPropagation();
+ !this.isSelected(true) && SelectionManager.SelectDoc(this, false);
+ }
// the touch onContextMenu is button 0, the pointer onContextMenu is button 2
if (e) {
if (e.button === 0 && !e.ctrlKey || e.isDefaultPrevented()) {
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index eab365445..7a010532f 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -94,13 +94,13 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
});
let newFacet: Opt<Doc>;
if (facetHeader === "text" || rtfields / allCollectionDocs.length > 0.1) {
- newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true });
+ newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true });
Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
newFacet._textBoxPadding = 4;
const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`;
newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" });
} else if (facetHeader !== "tags" && nonNumbers / facetValues.length < .1) {
- newFacet = Docs.Create.SliderDocument({ title: facetHeader, treeViewExpandedView: "layout", treeViewOpen: true });
+ newFacet = Docs.Create.SliderDocument({ title: facetHeader, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true });
const newFacetField = Doc.LayoutFieldKey(newFacet);
const ranged = Doc.readDocRangeFilter(targetDoc, facetHeader);
Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
@@ -118,7 +118,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
newFacet.title = facetHeader;
newFacet.treeViewOpen = true;
newFacet.type = DocumentType.COL;
- const capturedVariables = { layoutDoc: targetDoc, dataDoc: (targetDoc.data as any)[0][DataSym] };
+ const capturedVariables = { layoutDoc: targetDoc, _stayInCollection: true, _hideContextMenu: true, dataDoc: (targetDoc.data as any)[0][DataSym] };
newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, "${facetHeader}")`, {}, capturedVariables);
}
newFacet && Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet);
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index f9b62ceb5..6e96513c7 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -45,10 +45,12 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };
specificContextMenu = (): void => {
- const cm = ContextMenu.Instance;
- cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
- !Doc.UserDoc().noviceMode && cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
- !Doc.UserDoc().noviceMode && cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
+ if (!Doc.UserDoc().noviceMode) {
+ const cm = ContextMenu.Instance;
+ cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
+ cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
+ cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
+ }
}
componentWillUnmount() {