aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Wilkins <samuel_wilkins@brown.edu>2019-06-12 23:22:58 -0400
committerSam Wilkins <samuel_wilkins@brown.edu>2019-06-12 23:22:58 -0400
commit74dee5f76ffc5bbdd07caafb4273aaf485dec1b9 (patch)
tree8ec0f1a65a292f0f36003e39f14e832a6128f651
parentc0aa7c79258ea8409611da710dc802e3481c34d8 (diff)
beginnings of nested golden layout
-rw-r--r--src/client/documents/Documents.ts18
-rw-r--r--src/client/util/DocumentManager.ts4
-rw-r--r--src/client/util/DragManager.ts8
-rw-r--r--src/client/util/TooltipTextMenu.tsx2
-rw-r--r--src/client/views/MainOverlayTextBox.tsx4
-rw-r--r--src/client/views/MainView.tsx20
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx162
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/ParentDocumentSelector.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx12
11 files changed, 158 insertions, 80 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index ab61b915c..b346e1570 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -35,6 +35,7 @@ import { dropActionType } from "../util/DragManager";
import { DateField } from "../../new_fields/DateField";
import { UndoManager } from "../util/UndoManager";
import { RouteStore } from "../../server/RouteStore";
+import { CollectionDockingView } from "../views/collections/CollectionDockingView";
var requestImageSize = require('request-image-size');
var path = require('path');
@@ -315,6 +316,23 @@ export namespace Docs {
export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id);
}
+ export type DocConfig = {
+ doc: Doc,
+ initialWidth?: number
+ }
+ export function StandardCollectionDockingDocument(configs: Array<DocConfig>, options: DocumentOptions, id?: string, type: string = "row") {
+ let layoutConfig = {
+ content: [
+ {
+ type: type,
+ content: [
+ ...configs.map(config => CollectionDockingView.makeDocumentConfig(config.doc, config.initialWidth))
+ ]
+ }
+ ]
+ };
+ return DockDocument(configs.map(c => c.doc), JSON.stringify(layoutConfig), options, id);
+ }
export function CaptionDocument(doc: Doc) {
const captionDoc = Doc.MakeAlias(doc);
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 65c4b9e4b..72d9f7e76 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -134,7 +134,7 @@ export class DocumentManager {
const actualDoc = Doc.MakeAlias(docDelegate);
actualDoc.libraryBrush = true;
if (linkPage !== undefined) actualDoc.curPage = linkPage;
- (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc);
+ (dockFunc || CollectionDockingView.AddRightSplit)(actualDoc);
} else {
let contextView: DocumentView | null;
docDelegate.libraryBrush = true;
@@ -142,7 +142,7 @@ export class DocumentManager {
contextDoc.panTransformType = "Ease";
contextView.props.focus(contextDoc);
} else {
- (dockFunc || CollectionDockingView.Instance.AddRightSplit)(contextDoc);
+ (dockFunc || CollectionDockingView.AddRightSplit)(contextDoc);
}
}
}
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 1e84a0db0..7625b0463 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -26,8 +26,8 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
// if (this.props.isSelected() || this.props.isTopMost) {
if (e.button === 0) {
e.stopPropagation();
- if (e.shiftKey && CollectionDockingView.Instance) {
- CollectionDockingView.Instance.StartOtherDrag([await docFunc()], e);
+ if (e.shiftKey && CollectionDockingView.TopLevel) {
+ CollectionDockingView.TopLevel.StartOtherDrag([await docFunc()], e);
} else {
document.addEventListener("pointermove", onRowMove);
document.addEventListener("pointerup", onRowUp);
@@ -264,9 +264,9 @@ export namespace DragManager {
if (dragData instanceof DocumentDragData) {
dragData.userDropAction = e.ctrlKey || e.altKey ? "alias" : undefined;
}
- if (e.shiftKey && CollectionDockingView.Instance) {
+ if (e.shiftKey && CollectionDockingView.TopLevel) {
AbortDrag();
- CollectionDockingView.Instance.StartOtherDrag(docs, {
+ CollectionDockingView.TopLevel.StartOtherDrag(docs, {
pageX: e.pageX,
pageY: e.pageY,
preventDefault: emptyFunction,
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index f517f757a..fa2483db5 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -194,7 +194,7 @@ export class TooltipTextMenu {
if (DocumentManager.Instance.getDocumentView(f)) {
DocumentManager.Instance.getDocumentView(f)!.props.focus(f);
}
- else if (CollectionDockingView.Instance) CollectionDockingView.Instance.AddRightSplit(f);
+ else if (CollectionDockingView.TopLevel) CollectionDockingView.AddRightSplit(f);
}
}));
}
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 24327b995..718979123 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -86,7 +86,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
addDocTab = (doc: Doc, location: string) => {
if (true) { // location === "onRight") { need to figure out stack to add "inTab"
- CollectionDockingView.Instance.AddRightSplit(doc);
+ CollectionDockingView.AddRightSplit(doc);
}
}
render() {
@@ -102,6 +102,6 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
</div>
</ div>;
}
- else return (null); Z
+ else return (null);
}
} \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 67a026897..426e2440a 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt, faBell } from '@fortawesome/free-solid-svg-icons';
+import { faClone, faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt, faBell } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, configure, observable, runInAction, trace } from 'mobx';
import { observer } from 'mobx-react';
@@ -106,6 +106,7 @@ export class MainView extends React.Component {
library.add(faFilm);
library.add(faMusic);
library.add(faTree);
+ library.add(faClone)
this.initEventListeners();
this.initAuthenticationRouters();
}
@@ -151,8 +152,11 @@ export class MainView extends React.Component {
const list = Cast(CurrentUserUtils.UserDocument.data, listSpec(Doc));
if (list) {
let freeformDoc = Docs.FreeformDocument([], { x: 0, y: 400, width: this.pwidth * .7, height: this.pheight, title: `WS collection ${list.length + 1}` });
- var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(CurrentUserUtils.UserDocument, 150), CollectionDockingView.makeDocumentConfig(freeformDoc, 600)] }] };
- let mainDoc = Docs.DockDocument([CurrentUserUtils.UserDocument, freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${list.length + 1}` }, id);
+ let configs = [
+ { doc: CurrentUserUtils.UserDocument, initialWidth: 150 },
+ { doc: freeformDoc, initialWidth: 600 }
+ ]
+ let mainDoc = Docs.StandardCollectionDockingDocument(configs, { title: `Workspace ${list.length + 1}` }, id);
list.push(mainDoc);
// bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
setTimeout(() => {
@@ -183,8 +187,8 @@ export class MainView extends React.Component {
}
openNotifsCol = () => {
- if (this._notifsCol && CollectionDockingView.Instance) {
- CollectionDockingView.Instance.AddRightSplit(this._notifsCol);
+ if (this._notifsCol && CollectionDockingView.TopLevel) {
+ CollectionDockingView.AddRightSplit(this._notifsCol);
}
}
@@ -240,6 +244,7 @@ export class MainView extends React.Component {
let addTextNode = action(() => Docs.TextDocument({ borderRounding: -1, width: 200, height: 200, title: "a text note" }));
let addColNode = action(() => Docs.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" }));
+ let addDockingNode = action(() => Docs.StandardCollectionDockingDocument([{ doc: addColNode(), initialWidth: 200 }], { width: 200, height: 200, title: "a nested docking freeform collection" }));
let addSchemaNode = action(() => Docs.SchemaDocument(["title"], [], { width: 200, height: 200, title: "a schema collection" }));
let addTreeNode = action(() => CurrentUserUtils.UserDocument);
//let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" }));
@@ -260,6 +265,7 @@ export class MainView extends React.Component {
[React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
[React.createRef<HTMLDivElement>(), "tree", "Add Tree", addTreeNode],
[React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode],
+ [React.createRef<HTMLDivElement>(), "clone", "Add Docking Frame", addDockingNode]
];
return < div id="add-nodes-menu" >
@@ -327,12 +333,12 @@ export class MainView extends React.Component {
switch (e.key) {
case "ArrowRight":
if (this.mainFreeform) {
- CollectionDockingView.Instance.AddRightSplit(this.mainFreeform!);
+ CollectionDockingView.AddRightSplit(this.mainFreeform!);
}
break;
case "ArrowLeft":
if (this.mainFreeform) {
- CollectionDockingView.Instance.CloseRightSplit(this.mainFreeform!);
+ CollectionDockingView.CloseRightSplit(this.mainFreeform!);
}
break;
case "o":
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 4d6721dc1..096c65092 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -16,7 +16,7 @@ export enum CollectionViewType {
Schema,
Docking,
Tree,
- Stacking
+ Stacking,
}
export interface CollectionRenderProps {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 1adb73bcf..dfb8fac35 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,9 +1,9 @@
import 'golden-layout/src/css/goldenlayout-base.css';
import 'golden-layout/src/css/goldenlayout-dark-theme.css';
-import { action, observable, reaction, Lambda } from "mobx";
+import { action, observable, reaction, Lambda, IReactionDisposer } from "mobx";
import { observer } from "mobx-react";
import * as ReactDOM from 'react-dom';
-import Measure from "react-measure";
+import Measure, { ContentRect } from "react-measure";
import * as GoldenLayout from "../../../client/goldenLayout";
import { Doc, Field, Opt, DocListCast } from "../../../new_fields/Doc";
import { FieldId } from "../../../new_fields/RefField";
@@ -26,7 +26,7 @@ import { CurrentUserUtils } from '../../../server/authentication/models/current_
@observer
export class CollectionDockingView extends React.Component<SubCollectionViewProps> {
- public static Instance: CollectionDockingView;
+ public static TopLevel: CollectionDockingView;
public static makeDocumentConfig(document: Doc, width?: number) {
return {
type: 'react-component',
@@ -35,11 +35,16 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
width: width,
props: {
documentId: document[Id],
- //collectionDockingView: CollectionDockingView.Instance
}
};
}
+ private makeDocConfig = (document: Doc, width?: number) => {
+ const config = CollectionDockingView.makeDocumentConfig(document, width);
+ (config.props as any).parent = this;
+ return config;
+ }
+
private _goldenLayout: any = null;
private _containerRef = React.createRef<HTMLDivElement>();
private _flush: boolean = false;
@@ -48,7 +53,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
constructor(props: SubCollectionViewProps) {
super(props);
- CollectionDockingView.Instance = this;
+ CollectionDockingView.TopLevel = this;
(window as any).React = React;
(window as any).ReactDOM = ReactDOM;
}
@@ -58,41 +63,69 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
this.hack = true;
this.undohack = UndoManager.StartBatch("goldenDrag");
dragDocs.map(dragDoc =>
- this.AddRightSplit(dragDoc, true).contentItems[0].tab._dragListener.
+ CollectionDockingView.AddRightSplit(dragDoc, true).contentItems[0].tab._dragListener.
onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 }));
}
- @action
- public OpenFullScreen(document: Doc) {
+ private openFullScreen = (document: Doc) => {
let newItemStackConfig = {
type: 'stack',
- content: [CollectionDockingView.makeDocumentConfig(document)]
+ content: [this.makeDocConfig(document)]
};
var docconfig = this._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, this._goldenLayout);
this._goldenLayout.root.contentItems[0].addChild(docconfig);
docconfig.callDownwards('_$init');
this._goldenLayout._$maximiseItem(docconfig);
- this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
+ this._ignoreStateChange = this.retrieveConfiguration();
this.stateChanged();
}
+ @action
+ public static OpenFullScreen(document: Doc, dockingView: CollectionDockingView = CollectionDockingView.TopLevel) {
+ dockingView.openFullScreen(document);
+ }
+
+ initializeConfiguration = (configText: string) => {
+ let configuration: any = JSON.parse(configText);
+ this.injectParentProp(configuration.content);
+ this._goldenLayout = new GoldenLayout(configuration);
+ }
+
+ retrieveConfiguration = () => {
+ let configuration: any = this._goldenLayout.toConfig();
+ this.injectParentProp(configuration.content, true);
+ return JSON.stringify(configuration);
+ }
+
+ injectParentProp = (contentArray: any[], reverse: boolean = false) => {
+ if (!contentArray || contentArray.length == 0) return;
+ contentArray.forEach(member => {
+ let baseCase = Object.keys(member).includes("props");
+ if (!baseCase) {
+ this.injectParentProp(member.content, reverse)
+ } else {
+ reverse ? delete member.props.parent : member.props.parent = this;
+ }
+ });
+ }
+
@undoBatch
@action
- public CloseRightSplit = (document: Doc): boolean => {
+ public static CloseRightSplit = (document: Doc, dockingView: CollectionDockingView = CollectionDockingView.TopLevel): boolean => {
let retVal = false;
- if (this._goldenLayout.root.contentItems[0].isRow) {
- retVal = Array.from(this._goldenLayout.root.contentItems[0].contentItems).some((child: any) => {
+ if (dockingView._goldenLayout.root.contentItems[0].isRow) {
+ retVal = Array.from(dockingView._goldenLayout.root.contentItems[0].contentItems).some((child: any) => {
if (child.contentItems.length === 1 && child.contentItems[0].config.component === "DocumentFrameRenderer" &&
Doc.AreProtosEqual(DocumentManager.Instance.getDocumentViewById(child.contentItems[0].config.props.documentId)!.Document, document)) {
child.contentItems[0].remove();
- this.layoutChanged(document);
+ dockingView.layoutChanged(document);
return true;
} else {
Array.from(child.contentItems).filter((tab: any) => tab.config.component === "DocumentFrameRenderer").some((tab: any, j: number) => {
if (Doc.AreProtosEqual(DocumentManager.Instance.getDocumentViewById(tab.config.props.documentId)!.Document, document)) {
child.contentItems[j].remove();
child.config.activeItemIndex = Math.max(child.contentItems.length - 1, 0);
- let docs = Cast(this.props.Document.data, listSpec(Doc));
+ let docs = Cast(dockingView.props.Document.data, listSpec(Doc));
docs && docs.indexOf(document) !== -1 && docs.splice(docs.indexOf(document), 1);
return true;
}
@@ -103,7 +136,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
});
}
if (retVal) {
- this.stateChanged();
+ dockingView.stateChanged();
}
return retVal;
}
@@ -112,23 +145,26 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
layoutChanged(removed?: Doc) {
this._goldenLayout.root.callDownwards('setSize', [this._goldenLayout.width, this._goldenLayout.height]);
this._goldenLayout.emit('stateChanged');
- this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
- if (removed) CollectionDockingView.Instance._removedDocs.push(removed);
+ this._ignoreStateChange = this.retrieveConfiguration();
+ if (removed) CollectionDockingView.TopLevel._removedDocs.push(removed);
this.stateChanged();
}
//
// Creates a vertical split on the right side of the docking view, and then adds the Document to that split
//
- @action
- public AddRightSplit = (document: Doc, minimize: boolean = false) => {
+ public static AddRightSplit = (document: Doc, minimize: boolean = false, dockingView: CollectionDockingView = CollectionDockingView.TopLevel) => {
+ return dockingView.addRightSplit(document, minimize);
+ }
+
+ private addRightSplit(document: Doc, minimize = false) {
let docs = Cast(this.props.Document.data, listSpec(Doc));
if (docs) {
docs.push(document);
}
let newItemStackConfig = {
type: 'stack',
- content: [CollectionDockingView.makeDocumentConfig(document)]
+ content: [this.makeDocConfig(document)]
};
var newContentItem = this._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, this._goldenLayout);
@@ -157,13 +193,17 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
return newContentItem;
}
- @action
- public AddTab = (stack: any, document: Doc) => {
+
+ public static AddTab = (stack: any, document: Doc, dockingView: CollectionDockingView = CollectionDockingView.TopLevel) => {
+ dockingView.addTab(stack, document);
+ }
+
+ private addTab = (stack: any, document: Doc) => {
let docs = Cast(this.props.Document.data, listSpec(Doc));
if (docs) {
docs.push(document);
}
- let docContentConfig = CollectionDockingView.makeDocumentConfig(document);
+ let docContentConfig = this.makeDocConfig(document);
var newContentItem = stack.layoutManager.createContentItem(docContentConfig, this._goldenLayout);
stack.addChild(newContentItem.contentItems[0], undefined);
this.layoutChanged();
@@ -173,10 +213,10 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
var config = StrCast(this.props.Document.dockingConfig);
if (config) {
if (!this._goldenLayout) {
- this._goldenLayout = new GoldenLayout(JSON.parse(config));
+ this.initializeConfiguration(config);
}
else {
- if (config === JSON.stringify(this._goldenLayout.toConfig())) {
+ if (config === this.retrieveConfiguration()) {
return;
}
try {
@@ -186,7 +226,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
this._goldenLayout.unbind('stackCreated', this.stackCreated);
} catch (e) { }
this._goldenLayout.destroy();
- this._goldenLayout = new GoldenLayout(JSON.parse(config));
+ this.initializeConfiguration(config);
}
this._goldenLayout.on('itemDropped', this.itemDropped);
this._goldenLayout.on('tabCreated', this.tabCreated);
@@ -204,13 +244,13 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
this._goldenLayout.init();
}
}
- reactionDisposer?: Lambda;
+ reactionDisposer?: IReactionDisposer;
componentDidMount: () => void = () => {
if (this._containerRef.current) {
this.reactionDisposer = reaction(
() => StrCast(this.props.Document.dockingConfig),
() => {
- if (!this._goldenLayout || this._ignoreStateChange !== JSON.stringify(this._goldenLayout.toConfig())) {
+ if (!this._goldenLayout || this._ignoreStateChange !== this.retrieveConfiguration()) {
// Because this is in a set timeout, if this component unmounts right after mounting,
// we will leak a GoldenLayout, because we try to destroy it before we ever create it
setTimeout(() => this.setupGoldenLayout(), 1);
@@ -218,7 +258,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
this._ignoreStateChange = "";
}, { fireImmediately: true });
- window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window
+ // window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window
}
}
componentWillUnmount: () => void = () => {
@@ -232,18 +272,19 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
}
if (this._goldenLayout) this._goldenLayout.destroy();
this._goldenLayout = null;
- window.removeEventListener('resize', this.onResize);
+ // window.removeEventListener('resize', this.onResize);
if (this.reactionDisposer) {
this.reactionDisposer();
}
}
@action
- onResize = (event: any) => {
- var cur = this._containerRef.current;
-
+ onResize = (size: ContentRect) => {
// bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
- this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
+ // this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
+ if (this._goldenLayout) {
+ this._goldenLayout.updateSize(size.offset!.width, size.offset!.height);
+ }
}
@action
@@ -301,12 +342,12 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
@undoBatch
stateChanged = () => {
- let docs = Cast(CollectionDockingView.Instance.props.Document.data, listSpec(Doc));
- CollectionDockingView.Instance._removedDocs.map(theDoc =>
+ let docs = Cast(CollectionDockingView.TopLevel.props.Document.data, listSpec(Doc));
+ CollectionDockingView.TopLevel._removedDocs.map(theDoc =>
docs && docs.indexOf(theDoc) !== -1 &&
docs.splice(docs.indexOf(theDoc), 1));
- CollectionDockingView.Instance._removedDocs.length = 0;
- var json = JSON.stringify(this._goldenLayout.toConfig());
+ CollectionDockingView.TopLevel._removedDocs.length = 0;
+ var json = this.retrieveConfiguration();
this.props.Document.dockingConfig = json;
if (this.undohack && !this.hack) {
this.undohack.end();
@@ -315,18 +356,18 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
this.hack = false;
}
- itemDropped = () => {
+ private itemDropped = () => {
this.stateChanged();
}
- htmlToElement(html: string) {
+ private htmlToElement(html: string) {
var template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
return template.content.firstChild;
}
- tabCreated = async (tab: any) => {
+ private tabCreated = async (tab: any) => {
if (tab.hasOwnProperty("contentItem") && tab.contentItem.config.type !== "stack") {
if (tab.contentItem.config.fixed) {
tab.contentItem.parent.config.fixed = true;
@@ -346,7 +387,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
}
tab.setActive(true);
}
- ReactDOM.render(<ParentDocSelector Document={doc} addDocTab={(doc, location) => CollectionDockingView.Instance.AddTab(stack, doc)} />, upDiv);
+ ReactDOM.render(<ParentDocSelector Document={doc} addDocTab={(doc, location) => CollectionDockingView.AddTab(stack, doc)} />, upDiv);
tab.reactComponents = [upDiv];
tab.element.append(upDiv);
counter.DashDocId = tab.contentItem.config.props.documentId;
@@ -368,13 +409,13 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
let doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId);
if (doc instanceof Doc) {
let theDoc = doc;
- CollectionDockingView.Instance._removedDocs.push(theDoc);
+ CollectionDockingView.TopLevel._removedDocs.push(theDoc);
}
tab.contentItem.remove();
});
}
- tabDestroyed = (tab: any) => {
+ private tabDestroyed = (tab: any) => {
if (tab.reactComponents) {
for (const ele of tab.reactComponents) {
ReactDOM.unmountComponentAtNode(ele);
@@ -383,7 +424,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
}
_removedDocs: Doc[] = [];
- stackCreated = (stack: any) => {
+ private stackCreated = (stack: any) => {
//stack.header.controlsContainer.find('.lm_popout').hide();
stack.header.controlsContainer.find('.lm_close') //get the close icon
.off('click') //unbind the current click handler
@@ -394,7 +435,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
let doc = await DocServer.GetRefField(contentItem.config.props.documentId);
if (doc instanceof Doc) {
let theDoc = doc;
- CollectionDockingView.Instance._removedDocs.push(theDoc);
+ CollectionDockingView.TopLevel._removedDocs.push(theDoc);
}
});
//}
@@ -410,8 +451,14 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
render() {
return (
- <div className="collectiondockingview-container" id="menuContainer"
- onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} ref={this._containerRef} />
+ <Measure onResize={this.onResize} offset>
+ {({ measureRef }) => (
+ <div ref={measureRef} style={{ width: "100%", height: "100%" }}>
+ <div className="collectiondockingview-container" id="menuContainer"
+ onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} ref={this._containerRef} />
+ </div>
+ )}
+ </Measure>
);
}
@@ -419,16 +466,23 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
interface DockedFrameProps {
documentId: FieldId;
- //collectionDockingView: CollectionDockingView
+ glContainer: any;
+ glEventHub: any;
+ parent: CollectionDockingView;
}
+
@observer
export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
_mainCont = React.createRef<HTMLDivElement>();
@observable private _panelWidth = 0;
@observable private _panelHeight = 0;
@observable private _document: Opt<Doc>;
+ private get parentProps(): SubCollectionViewProps {
+ return this.props.parent.props;
+ }
+
get _stack(): any {
- let parent = (this.props as any).glContainer.parent.parent;
+ let parent = this.props.glContainer.parent.parent;
if (this._document && this._document.excludeFromLibrary && parent.parent && parent.parent.contentItems.length > 1)
return parent.parent.contentItems[1];
return parent;
@@ -451,7 +505,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
if (this._mainCont.current && this._mainCont.current.children) {
let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont.current.children[0].firstChild as HTMLElement);
scale = Utils.GetScreenTransform(this._mainCont.current).scale;
- return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale);
+ return this.parentProps.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale);
}
return Transform.Identity();
}
@@ -469,9 +523,9 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
addDocTab = (doc: Doc, location: string) => {
if (location === "onRight") {
- CollectionDockingView.Instance.AddRightSplit(doc);
+ CollectionDockingView.AddRightSplit(doc);
} else {
- CollectionDockingView.Instance.AddTab(this._stack, doc);
+ CollectionDockingView.AddTab(this._stack, doc);
}
}
get content() {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 48da52ffa..b0a310ec1 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -123,7 +123,7 @@ class TreeView extends React.Component<TreeViewProps> {
return true;
}}
/>);
- let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document.data, listSpec(Doc), []) : [];
+ let dataDocs = CollectionDockingView.TopLevel ? Cast(CollectionDockingView.TopLevel.props.Document.data, listSpec(Doc), []) : [];
let openRight = dataDocs && dataDocs.indexOf(this.props.document) !== -1 ? (null) : (
<div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
<FontAwesomeIcon icon="angle-right" size="lg" />
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index f11af04a3..95183bd2c 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -29,8 +29,8 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index])));
docs.forEach(doc => map.delete(doc));
runInAction(() => {
- this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: this.props.Document }));
- this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target }));
+ this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.TopLevel.props.Document)).map(doc => ({ col: doc, target: this.props.Document }));
+ this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.TopLevel.props.Document)).map(([col, target]) => ({ col, target }));
});
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7750b9173..efba26c2c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -238,11 +238,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
expandedProtoDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized);
}
}
- if (maxLocation && maxLocation !== "inPlace" && CollectionDockingView.Instance) {
- let dataDocs = DocListCast(CollectionDockingView.Instance.props.Document.data);
+ if (maxLocation && maxLocation !== "inPlace" && CollectionDockingView.TopLevel) {
+ let dataDocs = DocListCast(CollectionDockingView.TopLevel.props.Document.data);
if (dataDocs) {
expandedDocs.forEach(maxDoc =>
- (!CollectionDockingView.Instance.CloseRightSplit(Doc.GetProto(maxDoc)) &&
+ (!CollectionDockingView.CloseRightSplit(Doc.GetProto(maxDoc)) &&
this.props.addDocTab(getDispDoc(maxDoc), maxLocation)));
}
} else {
@@ -270,8 +270,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._downX = e.clientX;
this._downY = e.clientY;
this._hitExpander = DocListCast(this.props.Document.subBulletDocs).length > 0;
- if (e.shiftKey && e.buttons === 1 && CollectionDockingView.Instance) {
- CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e);
+ if (e.shiftKey && e.buttons === 1 && CollectionDockingView.TopLevel) {
+ CollectionDockingView.TopLevel.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e);
e.stopPropagation();
} else {
if (this.active) e.stopPropagation(); // events stop at the lowest document that is active.
@@ -316,7 +316,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
}
fullScreenClicked = (): void => {
- CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(Doc.MakeCopy(this.props.Document, false));
+ CollectionDockingView.TopLevel && CollectionDockingView.OpenFullScreen(Doc.MakeCopy(this.props.Document, false));
SelectionManager.DeselectAll();
}