aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2020-09-17 12:26:08 +0530
committerusodhi <61431818+usodhi@users.noreply.github.com>2020-09-17 12:26:08 +0530
commitdce79728f8c8db971e8ca6d5865bb14bf9b278ef (patch)
tree2132d62df0d7213d6a97d83f4aefe692de9a661f /src
parent22a346805837cd7fc9afe8c9d22b40279cdf5b04 (diff)
parent2efd66bcef6329e4e816604ebd5a382e033dc2c6 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into acls_uv
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts3
-rw-r--r--src/client/util/CurrentUserUtils.ts79
-rw-r--r--src/client/util/DragManager.ts11
-rw-r--r--src/client/util/DropConverter.ts11
-rw-r--r--src/client/util/SettingsManager.tsx6
-rw-r--r--src/client/views/DocumentDecorations.tsx32
-rw-r--r--src/client/views/GlobalKeyHandler.ts2
-rw-r--r--src/client/views/MainView.scss27
-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/CollectionTreeView.tsx4
-rw-r--r--src/client/views/collections/TabDocView.scss5
-rw-r--r--src/client/views/collections/TabDocView.tsx107
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx30
-rw-r--r--src/client/views/nodes/FieldView.tsx2
-rw-r--r--src/client/views/nodes/FilterBox.tsx6
-rw-r--r--src/client/views/nodes/FontIconBox.tsx10
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx2
21 files changed, 195 insertions, 178 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 0911f3e04..36834d2df 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -92,6 +92,7 @@ export interface DocumentOptions {
y?: number;
z?: number;
author?: string;
+ _hideContextMenu?: boolean; // whether the context menu can be shown
dropAction?: dropActionType;
childDropAction?: dropActionType;
targetDropAction?: dropActionType;
@@ -133,7 +134,7 @@ export interface DocumentOptions {
opacity?: number;
defaultBackgroundColor?: string;
_isBackground?: boolean;
- "_isBackground-canClick"?: boolean; // a background document that you can still click on to edit its contents
+ _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged.
isLinkButton?: boolean;
_columnWidth?: number;
_fontSize?: string;
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 4bfa479a1..2e7fd1b21 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -65,8 +65,7 @@ export class CurrentUserUtils {
[this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
doc["template-mobile-button"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(queryTemplate) as any as Doc,
- removeDropProperties: new List<string>(["dropAction"]), title: "mobile button", icon: "mobile"
+ dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile"
});
}
@@ -81,8 +80,7 @@ export class CurrentUserUtils {
slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
doc["template-button-slides"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(slideTemplate) as any as Doc,
- removeDropProperties: new List<string>(["dropAction"]), title: "presentation slide", icon: "address-card"
+ dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card"
});
}
@@ -128,8 +126,7 @@ export class CurrentUserUtils {
doc["template-button-link"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(linkTemplate) as any as Doc,
- removeDropProperties: new List<string>(["dropAction"]), title: "link view", icon: "window-maximize", system: true
+ dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true
});
}
@@ -160,8 +157,7 @@ export class CurrentUserUtils {
doc["template-button-switch"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(box) as any as Doc,
- removeDropProperties: new List<string>(["dropAction"]), title: "data switch", icon: "toggle-on", system: true
+ dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true
});
}
@@ -210,28 +206,7 @@ export class CurrentUserUtils {
doc["template-button-detail"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(detailView) as any as Doc,
- removeDropProperties: new List<string>(["dropAction"]), title: "detail view", icon: "window-maximize", system: true
- });
- }
- if (doc["template-button-simple"] === undefined) {
- const { TextDocument, MasonryDocument, CarouselDocument } = Docs.Create;
-
- const openInTarget = ScriptField.MakeScript("openOnRight(self.doubleClickView)");
- const carousel = CarouselDocument([], {
- title: "data", _height: 350, _itemIndex: 0, "_carousel-caption-xMargin": 10, "_carousel-caption-yMargin": 10,
- onChildDoubleClick: openInTarget, backgroundColor: "#9b9b9b3F", system: true
- });
-
- const shared = { _chromeStatus: "disabled", _autoHeight: true, _xMargin: 0 };
- const detailViewOpts = { title: "detailView", _width: 300, _fontFamily: "Arial", _fontSize: "12px" };
- const detailView = Docs.Create.StackingDocument([carousel], { ...shared, ...detailViewOpts, system: true });
- detailView.isTemplateDoc = makeTemplate(detailView);
-
- doc["template-button-simple"] = CurrentUserUtils.ficon({
- onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(detailView) as any as Doc,
- removeDropProperties: new List<string>(["dropAction"]), title: "simple view", icon: "window-maximize", system: true
+ dragFactory: new PrefetchProxy(detailView) as any as Doc, title: "detail view", icon: "window-maximize", system: true
});
}
@@ -239,7 +214,6 @@ export class CurrentUserUtils {
doc["template-button-slides"] as Doc,
doc["template-mobile-button"] as Doc,
doc["template-button-detail"] as Doc,
- doc["template-button-simple"] as Doc,
doc["template-button-link"] as Doc,
//doc["template-button-switch"] as Doc]
];
@@ -247,7 +221,7 @@ export class CurrentUserUtils {
doc["template-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument(requiredTypes, {
title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title",
hidden: ComputedField.MakeFunction("self.userDoc.noviceMode") as any,
- userDoc: doc,
+ userDoc: doc, _stayInCollection: true, _hideContextMenu: true,
_autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled",
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
}));
@@ -302,8 +276,7 @@ export class CurrentUserUtils {
{ title: "Note Layouts", _height: 75, system: true }));
} else {
const curNoteTypes = Cast(doc["template-notes"], Doc, null);
- const requiredTypes = [doc["template-note-Note"] as any as Doc, doc["template-note-Idea"] as any as Doc,
- doc["template-note-Topic"] as any as Doc, doc["template-note-Todo"] as any as Doc];
+ const requiredTypes = [doc["template-note-Note"] as any as Doc, doc["template-note-Idea"] as any as Doc, doc["template-note-Topic"] as any as Doc];//, doc["template-note-Todo"] as any as Doc];
DocListCastAsync(curNoteTypes.data).then(async curNotes => {
await Promise.all(curNotes!);
requiredTypes.map(ntype => Doc.AddDocToList(curNoteTypes, "data", ntype));
@@ -484,7 +457,7 @@ export class CurrentUserUtils {
{ toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc },
{ toolTip: "Tap to create a mobile view in a new pane, drag for a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc },
{ toolTip: "Tap to create a document previewer in a new pane, drag for a document previewer", title: "Prev", icon: "expand", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyDocHolder as Doc },
- { toolTip: "Tap to create a custom header note document, drag for a custom header note", title: "Custom", icon: "window-maximize", click: 'openOnRight(delegateDragFactory(this.dragFactory))', drag: 'delegateDragFactory(this.dragFactory)', dragFactory: doc.emptyHeader as Doc, noviceMode: true },
+ { toolTip: "Tap to create a custom header note document, drag for a custom header note", title: "Custom", icon: "window-maximize", click: 'openOnRight(delegateDragFactory(this.dragFactory))', drag: 'delegateDragFactory(this.dragFactory)', dragFactory: doc.emptyHeader as Doc },
{ toolTip: "Toggle a Calculator REPL", title: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' },
];
@@ -503,7 +476,7 @@ export class CurrentUserUtils {
}
const buttons = CurrentUserUtils.creatorBtnDescriptors(doc).filter(d => !alreadyCreatedButtons?.includes(d.title));
const creatorBtns = buttons.map(({ title, toolTip, icon, ignoreClick, drag, click, ischecked, activeInkPen, backgroundColor, dragFactory, noviceMode, clickFactory }) => Docs.Create.FontIconDocument({
- _nativeWidth: 50, _nativeHeight: 50, _width: 35, _height: 35, _stayInCollection: true,
+ _nativeWidth: 50, _nativeHeight: 50, _width: 35, _height: 35,
icon,
title,
toolTip,
@@ -514,7 +487,9 @@ export class CurrentUserUtils {
ischecked: ischecked ? ComputedField.MakeFunction(ischecked) : undefined,
activeInkPen,
backgroundColor,
- removeDropProperties: new List<string>(["dropAction"]),
+ _hideContextMenu: true,
+ removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
+ _stayInCollection: true,
dragFactory,
clickFactory,
userDoc: noviceMode ? undefined as any : doc,
@@ -524,7 +499,7 @@ export class CurrentUserUtils {
if (dragCreatorSet === undefined) {
doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, {
- title: "Basic Item Creators", _showTitle: "title", _xMargin: 0,
+ title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true,
_autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled",
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
}));
@@ -567,12 +542,13 @@ export class CurrentUserUtils {
Docs.Create.FontIconDocument({
icon,
iconShape: "square",
+ _stayInCollection: true,
+ _hideContextMenu: true,
title,
target,
_backgroundColor: "black",
dropAction: "alias",
- removeDropProperties: new List<string>(["dropAction"]),
- childDropAction: "same",
+ removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
_width: 60,
_height: 60,
watchedDocuments,
@@ -584,6 +560,7 @@ export class CurrentUserUtils {
doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, {
title: "menuItemPanel",
+ childDropAction: "alias",
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
_backgroundColor: "black",
_gridGap: 0,
@@ -741,14 +718,14 @@ export class CurrentUserUtils {
// setup a color picker
if (doc.myColorPicker === undefined) {
const color = Docs.Create.ColorDocument({
- title: "color picker", _width: 300, dropAction: "alias", forceActive: true, removeDropProperties: new List<string>(["dropAction", "forceActive"]), system: true
+ title: "color picker", _width: 300, dropAction: "alias", _hideContextMenu: true, _stayInCollection: true, forceActive: true, removeDropProperties: new List<string>(["dropAction", "_stayInCollection", "_hideContextMenu", "forceActive"]), system: true
});
doc.myColorPicker = new PrefetchProxy(color);
}
if (doc.myTools === undefined) {
const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], {
- title: "My Tools", _width: 500, _yMargin: 20, lockedPosition: true, _chromeStatus: "disabled", forceActive: true, system: true
+ title: "My Tools", _width: 500, _yMargin: 20, lockedPosition: true, _chromeStatus: "disabled", forceActive: true, system: true, _stayInCollection: true, _hideContextMenu: true,
})) as any as Doc;
doc.myTools = toolsStack;
@@ -810,7 +787,7 @@ export class CurrentUserUtils {
if (doc.myFilter === undefined) {
doc.myFilter = new PrefetchProxy(Docs.Create.FilterDocument({
title: "FilterDoc", _height: 500,
- treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
+ treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none",
treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false,
lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
}));
@@ -861,16 +838,16 @@ export class CurrentUserUtils {
})) as any as Doc
static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
- ...opts, dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
+ ...opts, dropAction: "alias", removeDropProperties: new List<string>(["dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
})) as any as Doc
/// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
static setupDockedButtons(doc: Doc) {
if (doc["dockedBtn-undo"] === undefined) {
- doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), toolTip: "click to undo", title: "undo", icon: "undo-alt", system: true });
+ doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), _stayInCollection: true, dropAction: "alias", _hideContextMenu: true, removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "click to undo", title: "undo", icon: "undo-alt", system: true });
}
if (doc["dockedBtn-redo"] === undefined) {
- doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), toolTip: "click to redo", title: "redo", icon: "redo-alt", system: true });
+ doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), _stayInCollection: true, dropAction: "alias", _hideContextMenu: true, removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "click to redo", title: "redo", icon: "redo-alt", system: true });
}
if (doc.dockedBtns === undefined) {
doc.dockedBtns = CurrentUserUtils.blist({ title: "docked buttons", ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]);
@@ -902,12 +879,15 @@ export class CurrentUserUtils {
// Import sidebar is where shared documents are contained
static setupImportSidebar(doc: Doc) {
if (doc.myImportDocs === undefined) {
- doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "My ImportDocuments", forceActive: true, ignoreClick: true, _showTitle: "title", childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, lockedPosition: true, _chromeStatus: "disabled", system: true }));
+ doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
+ title: "My ImportDocuments", forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true,
+ childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, lockedPosition: true, _chromeStatus: "disabled", system: true
+ }));
}
if (doc.myImportPanel === undefined) {
const uploads = Cast(doc.myImportDocs, Doc, null);
- const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _backgroundColor: "black", title: "Import", icon: "upload", system: true });
- doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, lockedPosition: true, system: true }));
+ const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _backgroundColor: "black", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true });
+ doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, lockedPosition: true, system: true }));
}
}
@@ -964,6 +944,7 @@ export class CurrentUserUtils {
doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode;
doc.title = Doc.CurrentUserEmail;
doc.userColor = "orange";
+ doc._raiseWhenDragged = true;
doc.activeInkPen = doc;
doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)");
doc.activeInkWidth = StrCast(doc.activeInkWidth, "1");
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 367155c90..91ffab41d 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" | "same" | undefined; // undefined = move
+export type dropActionType = "alias" | "copy" | "move" | "same" | "none" | undefined; // undefined = move
export function SetupDrag(
_reference: React.RefObject<HTMLElement>,
docFunc: () => Doc | Promise<Doc> | undefined,
@@ -129,9 +129,10 @@ export namespace DragManager {
treeViewDoc?: Doc;
dontHideOnDrop?: boolean;
offset: number[];
- dropAction: dropActionType;
+ userDropAction: dropActionType; // the user requested drop action -- this will be honored as specified by modifier keys
+ defaultDropAction?: dropActionType; // an optionally specified default drop action when there is no user drop actionl - this will be honored if there is no user drop action
+ dropAction: dropActionType; // a drop action request by the initiating code. the actual drop action may be different -- eg, if the request is 'alias', but the document is dropped within the same collection, the drop action will be switched to 'move'
removeDropProperties?: string[];
- userDropAction: dropActionType;
moveDocument?: MoveFunction;
removeDocument?: RemoveFunction;
isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts
@@ -223,6 +224,7 @@ export namespace DragManager {
};
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);
+ return true;
}
// drag a button template and drop a new button
@@ -319,6 +321,7 @@ export namespace DragManager {
export let docsBeingDragged: Doc[] = [];
export let CanEmbed = false;
export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
+ if (dragData.dropAction === "none") return;
const batch = UndoManager.StartBatch("dragging");
eles = eles.filter(e => e);
CanEmbed = false;
@@ -417,7 +420,7 @@ export namespace DragManager {
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;
+ dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : dragData.defaultDropAction;
}
if (e?.shiftKey && dragData.draggedDocuments.length === 1) {
dragData.dropAction = dragData.userDropAction || "same";
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 1bbd46938..32817eefd 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -2,12 +2,13 @@ import { DragManager } from "./DragManager";
import { Doc, DocListCast, Opt } from "../../fields/Doc";
import { DocumentType } from "../documents/DocumentTypes";
import { ObjectField } from "../../fields/ObjectField";
-import { StrCast } from "../../fields/Types";
+import { StrCast, Cast } from "../../fields/Types";
import { Docs } from "../documents/Documents";
import { ScriptField, ComputedField } from "../../fields/ScriptField";
import { RichTextField } from "../../fields/RichTextField";
import { ImageField } from "../../fields/URLField";
import { Scripting } from "./Scripting";
+import { listSpec } from "../../fields/Schema";
//
// converts 'doc' into a template that can be used to render other documents.
@@ -54,7 +55,13 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
let dbox = doc;
// bcz: isButtonBar is intended to allow a collection of linear buttons to be dropped and nested into another collection of buttons... it's not being used yet, and isn't very elegant
if (doc.type === DocumentType.FONTICON || StrCast(Doc.Layout(doc).layout).includes("FontIconBox")) {
- //dbox = Doc.MakeAlias(doc); // don't need to do anything if dropping an icon doc onto an icon bar since there should be no layout data for an icon
+ if (data.removeDropProperties || dbox.removeDropProperties) {
+ //dbox = Doc.MakeAlias(doc); // don't need to do anything if dropping an icon doc onto an icon bar since there should be no layout data for an icon
+ dbox = Doc.MakeAlias(dbox);
+ const dragProps = Cast(dbox.removeDropProperties, listSpec("string"), []);
+ const remProps = (data.removeDropProperties || []).concat(Array.from(dragProps));
+ remProps.map(prop => dbox[prop] = undefined);
+ }
} else if (!doc.onDragStart && !doc.isButtonBar) {
const layoutDoc = doc;// doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
if (layoutDoc.type !== DocumentType.FONTICON) {
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index d4c92b20f..5b8fe3576 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -118,9 +118,9 @@ export class SettingsManager extends React.Component<{}> {
checked={BoolCast(Doc.UserDoc()["documentLinksButton-hideEnd"])} />
</div>
<div>
- Autoscroll
- <input type="checkbox" onChange={e => Doc.UserDoc()._noAutoscroll = !Doc.UserDoc()._noAutoscroll}
- checked={!BoolCast(Doc.UserDoc()._noAutoscroll)} />
+ <div className="preferences-check">Raise on drag</div>
+ <input type="checkbox" onChange={e => Doc.UserDoc()._raiseWhenDragged = !Doc.UserDoc()._raiseWhenDragged}
+ checked={BoolCast(Doc.UserDoc()._raiseWhenDragged)} />
</div>
</div>
</div>;
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..f64449616 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -382,4 +382,31 @@
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;
+ padding-right: 0 !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/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 1aa3a9364..61c8f580d 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -52,7 +52,7 @@ export interface TreeViewProps {
indentDocument?: () => void;
outdentDocument?: () => void;
ScreenToLocalTransform: () => Transform;
- backgroundColor?: (doc: Doc, renderDepth: number) => string | undefined;
+ backgroundColor?: (doc: Opt<Doc>, renderDepth: number) => string | undefined;
outerXf: () => { translateX: number, translateY: number };
treeView: CollectionTreeView;
parentKey: string;
@@ -655,7 +655,7 @@ class TreeView extends React.Component<TreeViewProps> {
dropAction: dropActionType,
addDocTab: (doc: Doc, where: string) => boolean,
pinToPres: (document: Doc) => void,
- backgroundColor: undefined | ((document: Doc, renderDepth: number) => string | undefined),
+ backgroundColor: undefined | ((document: Opt<Doc>, renderDepth: number) => string | undefined),
screenToLocalXf: () => Transform,
outerXf: () => { translateX: number, translateY: number },
active: (outsideReaction?: boolean) => boolean,
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 84dc6c9fb..f89285923 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -1,3 +1,5 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
import 'golden-layout/src/css/goldenlayout-base.css';
import 'golden-layout/src/css/goldenlayout-dark-theme.css';
import { clamp } from 'lodash';
@@ -10,7 +12,7 @@ import { FieldId } from "../../../fields/RefField";
import { listSpec } from '../../../fields/Schema';
import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils } from "../../../Utils";
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils";
import { DocServer } from "../../DocServer";
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { DocumentManager } from '../../util/DocumentManager';
@@ -22,13 +24,11 @@ import { undoBatch, UndoManager } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
import { PresBox } from '../nodes/PresBox';
import { CollectionDockingView } from './CollectionDockingView';
-import "./TabDocView.scss";
import { CollectionDockingViewMenu } from './CollectionDockingViewMenu';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
import { CollectionViewType } from './CollectionView';
+import "./TabDocView.scss";
import React = require("react");
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Tooltip } from '@material-ui/core';
const _global = (window /* browser */ || global /* node */) as any;
interface TabDocViewProps {
@@ -72,11 +72,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
tab.setActive(true);
}
};
- const onPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, (e) => {
- !e.defaultPrevented && DragManager.StartDocumentDrag([dragHdl], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY);
- return !e.defaultPrevented;
- }, returnFalse, emptyFunction);
+ const dragBtnDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e, e => !e.defaultPrevented && DragManager.StartDocumentDrag([dragHdl], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY), returnFalse, emptyFunction);
};
// select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
@@ -94,20 +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";
- tab._disposers.buttonDisposer = reaction(() => this.view, (view) => view &&
- [ReactDOM.render(
- <span title="Drag as document" className="collectionDockingView-drag" onPointerDown={onPointerDown} >
- <CollectionDockingViewMenu views={() => [view]} Stack={stack} />
- </span>, dragHdl),
- tab._disposers.buttonDisposer?.()],
+ 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 }) => {
@@ -126,6 +116,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
});
}
}
+
/**
* Adds a document to the presentation view
**/
@@ -154,13 +145,13 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
}
}
+
/**
* Adds a document to the presentation view
**/
@undoBatch
@action
public static UnpinDoc(doc: Doc) {
- //add this new doc to props.Document
const curPres = CurrentUserUtils.ActivePresentation;
if (curPres) {
const ind = DocListCast(curPres.data).findIndex((val) => Doc.AreProtosEqual(val, doc));
@@ -169,20 +160,18 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
componentDidMount() {
- const color = () => StrCast(this._document?._backgroundColor, this._document && CollectionDockingView.Instance?.props.backgroundColor?.(this._document, 0) || "white");
const selected = () => SelectionManager.SelectedDocuments().some(v => v.props.Document === this._document);
- const updateTabColor = () => this.tab?.titleElement[0] && (this.tab.titleElement[0].style.backgroundColor = selected() ? color() : "");
- const observer = new _global.ResizeObserver(action((entries: any) => {
+ new _global.ResizeObserver(action((entries: any) => {
for (const entry of entries) {
this._panelWidth = entry.contentRect.width;
this._panelHeight = entry.contentRect.height;
}
- updateTabColor();
- }));
- observer.observe(this.props.glContainer._element[0]);
+ })).observe(this.props.glContainer._element[0]);
this.props.glContainer.layoutManager.on("activeContentItemChanged", this.onActiveContentItemChanged);
this.props.glContainer.tab?.isActive && this.onActiveContentItemChanged();
- this._tabReaction = reaction(() => ({ views: SelectionManager.SelectedDocuments(), color: color() }), updateTabColor, { fireImmediately: true });
+ this._tabReaction = reaction(() => ({ selected: selected(), color: this.tabColor, title: this.tab.titleElement[0] }),
+ ({ selected, color, title }) => title && (title.style.backgroundColor = selected ? color : ""),
+ { fireImmediately: true });
}
componentWillUnmount() {
@@ -196,30 +185,23 @@ export class TabDocView extends React.Component<TabDocViewProps> {
this._isActive = this.props.glContainer.tab.isActive;
(CollectionDockingView.Instance as any)._goldenLayout?.isInitialised && CollectionDockingView.Instance.stateChanged();
!this._isActive && this._document && Doc.UnBrushDoc(this._document); // bcz: bad -- trying to simulate a pointer leave event when a new tab is opened up on top of an existing one.
- // this._isActive && this.view && SelectionManager.SelectDoc(this.view, false);
}
}
- get layoutDoc() { return this._document && Doc.Layout(this._document); }
nativeAspect = () => this.nativeWidth() ? this.nativeWidth() / this.nativeHeight() : 0;
panelWidth = () => this.layoutDoc?.maxWidth ? Math.min(Math.max(NumCast(this.layoutDoc._width), NumCast(this.layoutDoc._nativeWidth)), this._panelWidth) :
(this.nativeAspect() && this.nativeAspect() < this._panelWidth / this._panelHeight ? this._panelHeight * this.nativeAspect() : this._panelWidth)
panelHeight = () => this.nativeAspect() && this.nativeAspect() > this._panelWidth / this._panelHeight ? this._panelWidth / this.nativeAspect() : this._panelHeight;
nativeWidth = () => !this.layoutDoc?._fitWidth ? NumCast(this.layoutDoc?._nativeWidth) || this._panelWidth : 0;
nativeHeight = () => !this.layoutDoc?._fitWidth ? NumCast(this.layoutDoc?._nativeHeight) || this._panelHeight : 0;
-
contentScaling = () => {
- const nativeH = this.nativeHeight();
- const nativeW = this.nativeWidth();
+ const nativeH = NumCast(this.layoutDoc?._nativeHeight);
+ const nativeW = NumCast(this.layoutDoc?._nativeWidth);
let scaling = 1;
- if (!this.layoutDoc?._fitWidth && (!nativeW || !nativeH)) {
- scaling = 1;
- } else if (NumCast(this.layoutDoc?._nativeWidth) && ((this.layoutDoc?._fitWidth) ||
- this._panelHeight / NumCast(this.layoutDoc?._nativeHeight) > this._panelWidth / NumCast(this.layoutDoc?._nativeWidth))) {
- scaling = this._panelWidth / NumCast(this.layoutDoc?._nativeWidth);
+ if (nativeW && (this.layoutDoc?._fitWidth || this._panelHeight / nativeH > this._panelWidth / nativeW)) {
+ scaling = this._panelWidth / nativeW; // width-limited or fitWidth
} else if (nativeW && nativeH) {
- const wscale = this.panelWidth() / nativeW;
- scaling = wscale * nativeH > this._panelHeight ? this._panelHeight / nativeH : wscale;
+ scaling = this._panelHeight / nativeH; // height-limited
}
return scaling;
}
@@ -234,6 +216,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
@computed get previewPanelCenteringOffset() { return this.nativeWidth() ? (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2 : 0; }
@computed get widthpercent() { return this.nativeWidth() ? `${(this.nativeWidth() * this.contentScaling()) / this._panelWidth * 100}% ` : undefined; }
+ @computed get layoutDoc() { return this._document && Doc.Layout(this._document); }
// adds a tab to the layout based on the locaiton parameter which can be:
// close[:{left,right,top,bottom}] - e.g., "close" will close the tab, "close:left" will close the left tab,
@@ -244,10 +227,10 @@ export class TabDocView extends React.Component<TabDocViewProps> {
// inPlace - will add the document to any collection along the path from the document to the docking view that has a field isInPlaceContainer. if none is found, inPlace adds a tab to current stack
addDocTab = (doc: Doc, location: string, libraryPath?: Doc[]) => {
SelectionManager.DeselectAll();
- if (doc._viewType === CollectionViewType.Docking) return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
- const locationFields = location.split(":");
+ const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
const locationParams = locationFields.length > 1 ? locationFields[1] : "";
switch (locationFields[0]) {
+ case "dashboard": return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
case "replace": return CollectionDockingView.ReplaceTab(doc, locationParams, this.stack);
@@ -257,42 +240,44 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
}
- @computed get renderContentBounds() {
+ @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, CollectionDockingView.Instance.props.backgroundColor?.(this._document, 0))); }
+ @computed get renderBounds() {
const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0];
const xbounds = bounds[2] - bounds[0];
const ybounds = bounds[3] - bounds[1];
const dim = Math.max(xbounds, ybounds);
return { l: bounds[0] + xbounds / 2 - dim / 2, t: bounds[1] + ybounds / 2 - dim / 2, cx: bounds[0] + xbounds / 2, cy: bounds[1] + ybounds / 2, dim };
}
- @computed get miniLeft() { return 50 + (NumCast(this._document?._panX) - this.renderContentBounds.cx) / this.renderContentBounds.dim * 100 - this.miniWidth / 2; }
- @computed get miniTop() { return 50 + (NumCast(this._document?._panY) - this.renderContentBounds.cy) / this.renderContentBounds.dim * 100 - this.miniHeight / 2; }
- @computed get miniWidth() { return this.panelWidth() / NumCast(this._document?._viewScale, 1) / this.renderContentBounds.dim * 100; }
- @computed get miniHeight() { return this.panelHeight() / NumCast(this._document?._viewScale, 1) / this.renderContentBounds.dim * 100; }
childLayoutTemplate = () => Cast(this._document?.childLayoutTemplate, Doc, null);
returnMiniSize = () => NumCast(this._document?._miniMapSize, 150);
miniDown = (e: React.PointerEvent) => {
- this._document && setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
- this._document!._panX = clamp(NumCast(this._document!._panX) + delta[0] / this.returnMiniSize() * this.renderContentBounds.dim, this.renderContentBounds.l, this.renderContentBounds.l + this.renderContentBounds.dim);
- this._document!._panY = clamp(NumCast(this._document!._panY) + delta[1] / this.returnMiniSize() * this.renderContentBounds.dim, this.renderContentBounds.t, this.renderContentBounds.t + this.renderContentBounds.dim);
+ const doc = this._document;
+ const miniSize = this.returnMiniSize();
+ doc && setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
+ doc._panX = clamp(NumCast(doc._panX) + delta[0] / miniSize * this.renderBounds.dim, this.renderBounds.l, this.renderBounds.l + this.renderBounds.dim);
+ doc._panY = clamp(NumCast(doc._panY) + delta[1] / miniSize * this.renderBounds.dim, this.renderBounds.t, this.renderBounds.t + this.renderBounds.dim);
return false;
}), emptyFunction, emptyFunction);
}
- getCurrentFrame = (): number => {
- const presTargetDoc = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex].presentationTargetDoc, Doc, null);
- return Cast(presTargetDoc._currentFrame, "number", null);
+ getCurrentFrame = () => {
+ return NumCast(Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex].presentationTargetDoc, Doc, null)._currentFrame);
}
-
renderMiniMap() {
+ const miniWidth = this.panelWidth() / NumCast(this._document?._viewScale, 1) / this.renderBounds.dim * 100;
+ const miniHeight = this.panelHeight() / NumCast(this._document?._viewScale, 1) / this.renderBounds.dim * 100;
+ const miniLeft = 50 + (NumCast(this._document?._panX) - this.renderBounds.cx) / this.renderBounds.dim * 100 - miniWidth / 2;
+ const miniTop = 50 + (NumCast(this._document?._panY) - this.renderBounds.cy) / this.renderBounds.dim * 100 - miniHeight / 2;
+ const miniSize = this.returnMiniSize();
return <>
{this._document?.hideMinimap ? (null) :
- <div className="miniMap" style={{ width: this.returnMiniSize(), height: this.returnMiniSize(), background: StrCast(this._document!._backgroundColor, StrCast(this._document!.backgroundColor, CollectionDockingView.Instance.props.backgroundColor?.(this._document!, 0))), }}>
+ <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.tabColor }}>
<CollectionFreeFormView
Document={this._document!}
LibraryPath={emptyPath}
CollectionView={undefined}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
- ChildLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid havin to set stuff like this.
+ ChildLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
noOverlay={true} // don't render overlay Docs since they won't scale
active={returnTrue}
select={emptyFunction}
@@ -321,13 +306,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
fitToBox={true}
/>
<div className="miniOverlay" onPointerDown={this.miniDown} >
- <div className="miniThumb" style={{
- width: `${this.miniWidth}% `,
- height: `${this.miniHeight}% `,
- left: `${this.miniLeft}% `,
- top: `${this.miniTop}% `,
- }}
- />
+ <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% `, }} />
</div>
</div>}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1cae12a9d..85641531d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -217,7 +217,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const nd = [NumCast(layoutDoc._nativeWidth), NumCast(layoutDoc._nativeHeight)];
layoutDoc._width = NumCast(layoutDoc._width, 300);
layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? nd[1] / nd[0] * NumCast(layoutDoc._width) : 300);
- d._isBackground === undefined && !d["_isBackground-canClick"] && (d.zIndex = zsorted.length + 1 + i); // bringToFront
+ !d._isBackground && (d._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : d._raiseWhenDragged) && (d.zIndex = zsorted.length + 1 + i); // bringToFront
}
(docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments);
@@ -372,12 +372,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}
- getClusterColor = (doc: Doc) => {
+ getClusterColor = (doc: Opt<Doc>) => {
let clusterColor = this.props.backgroundColor?.(doc, this.props.renderDepth + 1);
- const cluster = NumCast(doc.cluster);
+ const cluster = NumCast(doc?.cluster);
if (this.Document._useClusters) {
if (this._clusterSets.length <= cluster) {
- setTimeout(() => this.updateCluster(doc), 0);
+ setTimeout(() => doc && this.updateCluster(doc), 0);
} else {
// choose a cluster color from a palette
const colors = ["#da42429e", "#31ea318c", "rgba(197, 87, 20, 0.55)", "#4a7ae2c4", "rgba(216, 9, 255, 0.5)", "#ff7601", "#1dffff", "yellow", "rgba(27, 130, 49, 0.55)", "rgba(0, 0, 0, 0.268)"];
@@ -839,7 +839,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
bringToFront = action((doc: Doc, sendToBack?: boolean) => {
- if (sendToBack || doc._isBackground || doc["_isBackground-canClick"]) {
+ if (sendToBack || doc._isBackground) {
doc.zIndex = 0;
} else if (doc.isInkMask) {
doc.zIndex = 5000;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 966355e8f..5ca57a193 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -87,7 +87,7 @@ export interface DocumentViewProps {
addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean;
pinToPres: (document: Doc) => void;
backgroundHalo?: () => boolean;
- backgroundColor?: (doc: Doc, renderDepth: number) => string | undefined;
+ backgroundColor?: (doc: Opt<Doc>, renderDepth: number) => string | undefined;
forcedBackgroundColor?: (doc: Doc) => string | undefined;
opacity?: () => number | undefined;
ChromeHeight?: () => number;
@@ -303,7 +303,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
(Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
let stopPropagate = true;
let preventDefault = true;
- !this.props.Document._isBackground && !this.props.Document["_isBackground-canClick"] && this.props.bringToFront(this.props.Document);
+ !this.props.Document._isBackground && (this.rootDoc._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : this.rootDoc._raiseWhenDragged) && this.props.bringToFront(this.rootDoc);
if (this._doubleTap && ((this.props.renderDepth && this.props.Document.type !== DocumentType.FONTICON) || this.onDoubleClickHandler)) {// && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
if (this._timeout) {
clearTimeout(this._timeout);
@@ -602,9 +602,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@undoBatch @action
- toggleLockInBack = () => {
- this.rootDoc["_isBackground-canClick"] = !this.rootDoc["_isBackground-canClick"];
- if (this.rootDoc["_isBackground-canClick"]) this.rootDoc.zIndex = 0;
+ toggleRaiseWhenDragged = () => {
+ this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined;
}
@undoBatch @action
@@ -753,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()) {
@@ -790,19 +794,20 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (!Doc.IsSystem(this.rootDoc) && this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Tree) {
const existingOnClick = cm.findByDescription("OnClick...");
const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+
+ const zorders = cm.findByDescription("ZOrder...");
+ const zorderItems: ContextMenuProps[] = zorders && "subitems" in zorders ? zorders.subitems : [];
+ zorderItems.push({ description: "Bring to Front", event: () => this.props.bringToFront(this.rootDoc, false), icon: "expand-arrows-alt" });
+ zorderItems.push({ description: "Send to Back", event: () => this.props.bringToFront(this.rootDoc, true), icon: "expand-arrows-alt" });
+ zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: this.toggleRaiseWhenDragged, icon: "expand-arrows-alt" });
+ !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" });
+
if (!this.Document.annotationOn) {
const options = cm.findByDescription("Options...");
const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
!this.props.treeViewDoc && this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform && optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
!options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
- const zorders = cm.findByDescription("ZOrder...");
- const zorderItems: ContextMenuProps[] = zorders && "subitems" in zorders ? zorders.subitems : [];
- zorderItems.push({ description: "Bring to Front", event: () => this.props.bringToFront(this.rootDoc, false), icon: "expand-arrows-alt" });
- zorderItems.push({ description: "Send to Back", event: () => this.props.bringToFront(this.rootDoc, true), icon: "expand-arrows-alt" });
- zorderItems.push({ description: this.rootDoc["_isBackground-canClick"] ? "Unlock from Back" : "Lock in Back", event: this.toggleLockInBack, icon: "expand-arrows-alt" });
- !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" });
-
onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" });
onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" });
@@ -1049,7 +1054,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@computed get ignorePointerEvents() {
return this.props.pointerEvents === "none" ||
- (SnappingManager.GetIsDragging() && this.Document["_isBackground-canClick"]) ||
(this.Document._isBackground && !this.isSelected() && !SnappingManager.GetIsDragging()) ||
(this.Document.type === DocumentType.INK && Doc.GetSelectedTool() !== InkTool.None);
}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c7a1dfcb0..0d29e43b8 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -39,7 +39,7 @@ export interface FieldViewProps {
pinToPres: (document: Doc) => void;
removeDocument?: (document: Doc | Doc[]) => boolean;
moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
- backgroundColor?: (document: Doc, renderDepth: number) => string | undefined;
+ backgroundColor?: (document: Opt<Doc>, renderDepth: number) => string | undefined;
ScreenToLocalTransform: () => Transform;
bringToFront: (doc: Doc, sendToBack?: boolean) => void;
active: (outsideReaction?: boolean) => boolean;
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() {
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 2d26c5c6d..89ea57f65 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -16,7 +16,7 @@ interface Props {
linkDoc?: Doc;
linkSrc?: Doc;
href?: string;
- backgroundColor: (doc: Doc, renderDepth: number) => string;
+ backgroundColor: (doc: Opt<Doc>, renderDepth: number) => string;
addDocTab: (document: Doc, where: string) => boolean;
location: number[];
}