diff options
| author | bobzel <zzzman@gmail.com> | 2022-08-03 09:01:29 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2022-08-03 09:01:29 -0400 |
| commit | 9c26b676be062f9bd0f1ab66f8ba40fc9ec85d42 (patch) | |
| tree | ba6f48f871ddc356fdf7fd51ce2465c6d9f80c69 /src/client/views/collections/CollectionDockingView.tsx | |
| parent | c1cd00c7664df694b867f4989a1f61d959390742 (diff) | |
| parent | 85dade366a9517796d1d80cee2be022d5cacdc93 (diff) | |
Merge branch 'master' into parker
Diffstat (limited to 'src/client/views/collections/CollectionDockingView.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 410 |
1 files changed, 230 insertions, 180 deletions
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 0830b6fdf..39e2cc17d 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,38 +1,35 @@ -import 'golden-layout/src/css/goldenlayout-base.css'; -import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx"; -import { observer } from "mobx-react"; +import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; import * as ReactDOM from 'react-dom'; -import * as GoldenLayout from "../../../client/goldenLayout"; -import { Doc, DocListCast, Opt } from "../../../fields/Doc"; +import * as GoldenLayout from '../../../client/goldenLayout'; +import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; -import { Cast, NumCast, StrCast } from "../../../fields/Types"; +import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { inheritParentAcls } from '../../../fields/util'; import { emptyFunction, incrementTitleCopy } from '../../../Utils'; -import { DocServer } from "../../DocServer"; +import { DocServer } from '../../DocServer'; import { Docs } from '../../documents/Documents'; -import { DocumentType } from '../../documents/DocumentTypes'; -import { CurrentUserUtils } from '../../util/CurrentUserUtils'; -import { DragManager } from "../../util/DragManager"; +import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; +import { DragManager } from '../../util/DragManager'; import { InteractionUtils } from '../../util/InteractionUtils'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SelectionManager } from '../../util/SelectionManager'; -import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { DashboardView } from '../DashboardView'; import { LightboxView } from '../LightboxView'; -import "./CollectionDockingView.scss"; +import './CollectionDockingView.scss'; import { CollectionFreeFormView } from './collectionFreeForm'; -import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView"; -import { CollectionViewType } from './CollectionView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { TabDocView } from './TabDocView'; -import React = require("react"); -const _global = (window /* browser */ || global /* node */) as any; +import React = require('react'); +const _global = (window /* browser */ || global) /* node */ as any; @observer export class CollectionDockingView extends CollectionSubView() { - @observable public static Instance: CollectionDockingView; + @observable public static Instance: CollectionDockingView | undefined; public static makeDocumentConfig(document: Doc, panelName?: string, width?: number) { return { type: 'react-component', @@ -41,8 +38,8 @@ export class CollectionDockingView extends CollectionSubView() { width: width, props: { documentId: document[Id], - panelName // name of tab that can be used to close or replace its contents - } + panelName, // name of tab that can be used to close or replace its contents + }, }; } @@ -50,14 +47,16 @@ export class CollectionDockingView extends CollectionSubView() { private _lightboxReactionDisposer?: IReactionDisposer; private _containerRef = React.createRef<HTMLDivElement>(); public _flush: UndoManager.Batch | undefined; - private _ignoreStateChange = ""; + private _ignoreStateChange = ''; public tabMap: Set<any> = new Set(); - public get HasFullScreen() { return this._goldenLayout._maximisedItem !== null; } + public get HasFullScreen() { + return this._goldenLayout._maximisedItem !== null; + } private _goldenLayout: any = null; constructor(props: SubCollectionViewProps) { super(props); - runInAction(() => CollectionDockingView.Instance = this); + runInAction(() => (CollectionDockingView.Instance = this)); //Why is this here? (window as any).React = React; (window as any).ReactDOM = ReactDOM; @@ -66,19 +65,18 @@ export class CollectionDockingView extends CollectionSubView() { /** * Switches from dragging a document around a freeform canvas to dragging it as a tab to be docked. - * + * * @param e fake mouse down event position data containing pageX and pageY coordinates * @param dragDocs the documents to be dragged * @param batch optionally an undo batch that has been started to use instead of starting a new batch - */ - public StartOtherDrag = (e: { pageX: number, pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => { - this._flush = this._flush ?? UndoManager.StartBatch("golden layout drag"); - const config = dragDocs.length === 1 ? CollectionDockingView.makeDocumentConfig(dragDocs[0]) : - { type: 'row', content: dragDocs.map(doc => CollectionDockingView.makeDocumentConfig(doc)) }; - const dragSource = this._goldenLayout.createDragSource(document.createElement("div"), config); + */ + public StartOtherDrag = (e: { pageX: number; pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => { + this._flush = this._flush ?? UndoManager.StartBatch('golden layout drag'); + const config = dragDocs.length === 1 ? CollectionDockingView.makeDocumentConfig(dragDocs[0]) : { type: 'row', content: dragDocs.map(doc => CollectionDockingView.makeDocumentConfig(doc)) }; + const dragSource = this._goldenLayout.createDragSource(document.createElement('div'), config); this.tabDragStart(dragSource, finishDrag); dragSource._dragListener.onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 }); - } + }; tabItemDropped = () => DragManager.CompleteWindowDrag?.(false); tabDragStart = (proxy: any, finishDrag?: (aborted: boolean) => void) => { @@ -88,7 +86,7 @@ export class CollectionDockingView extends CollectionSubView() { if (aborted) { proxy._dragListener.AbortDrag(); if (this._flush) { - this._flush.cancel(); // cancel the undo change being logged + this._flush.cancel(); // cancel the undo change being logged this._flush = undefined; this.setupGoldenLayout(); // restore golden layout to where it was before the drag (this is a no-op when using StartOtherDrag because the proxy dragged item was never in the golden layout) } @@ -96,21 +94,23 @@ export class CollectionDockingView extends CollectionSubView() { } finishDrag?.(aborted); }; - } + }; @undoBatch public CloseFullScreen = () => { this._goldenLayout._maximisedItem?.toggleMaximise(); this.stateChanged(); - } + }; @undoBatch public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean { - const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find((tab) => panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document); - if (tab) { - const j = tab.header.parent.contentItems.indexOf(tab.contentItem); - if (j !== -1) { - tab.header.parent.contentItems[j].remove(); - return CollectionDockingView.Instance.layoutChanged(); + if (CollectionDockingView.Instance) { + const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => (panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document)); + if (tab) { + const j = tab.header.parent.contentItems.indexOf(tab.contentItem); + if (j !== -1) { + tab.header.parent.contentItems[j].remove(); + return CollectionDockingView.Instance.layoutChanged(); + } } } @@ -121,19 +121,21 @@ export class CollectionDockingView extends CollectionSubView() { public static OpenFullScreen(doc: Doc) { SelectionManager.DeselectAll(); const instance = CollectionDockingView.Instance; - if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === "layout") { - return CurrentUserUtils.openDashboard(doc); + if (instance) { + if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === 'layout') { + return DashboardView.openDashboard(doc); + } + const newItemStackConfig = { + type: 'stack', + content: [CollectionDockingView.makeDocumentConfig(Doc.MakeAlias(doc))], + }; + const docconfig = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout); + instance._goldenLayout.root.contentItems[0].addChild(docconfig); + docconfig.callDownwards('_$init'); + instance._goldenLayout._$maximiseItem(docconfig); + instance._goldenLayout.emit('stateChanged'); + instance.stateChanged(); } - const newItemStackConfig = { - type: 'stack', - content: [CollectionDockingView.makeDocumentConfig(Doc.MakeAlias(doc))] - }; - const docconfig = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout); - instance._goldenLayout.root.contentItems[0].addChild(docconfig); - docconfig.callDownwards('_$init'); - instance._goldenLayout._$maximiseItem(docconfig); - instance._goldenLayout.emit('stateChanged'); - instance.stateChanged(); return true; } @@ -148,23 +150,23 @@ export class CollectionDockingView extends CollectionSubView() { const newContentItem = stack.layoutManager.createContentItem(newConfig, instance._goldenLayout); stack.addChild(newContentItem.contentItems[0], undefined); stack.contentItems[activeContentItemIndex].remove(); - return CollectionDockingView.Instance.layoutChanged(); + return instance.layoutChanged(); } - const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find((tab) => tab.contentItem.config.props.panelName === panelName); + const tab = Array.from(instance.tabMap.keys()).find(tab => tab.contentItem.config.props.panelName === panelName); if (tab) { tab.header.parent.addChild(newConfig, undefined); const j = tab.header.parent.contentItems.indexOf(tab.contentItem); !addToSplit && j !== -1 && tab.header.parent.contentItems[j].remove(); - return CollectionDockingView.Instance.layoutChanged(); + return instance.layoutChanged(); } return CollectionDockingView.AddSplit(document, panelName, stack, panelName); } - @undoBatch public static ToggleSplit(doc: Doc, location: string, stack?: any, panelName?: string) { - return Array.from(CollectionDockingView.Instance.tabMap.keys()).findIndex((tab) => tab.DashDoc === doc) !== -1 ? - CollectionDockingView.CloseSplit(doc) : CollectionDockingView.AddSplit(doc, location, stack, panelName); + return CollectionDockingView.Instance && Array.from(CollectionDockingView.Instance.tabMap.keys()).findIndex(tab => tab.DashDoc === doc) !== -1 + ? CollectionDockingView.CloseSplit(doc) + : CollectionDockingView.AddSplit(doc, location, stack, panelName); } // @@ -173,8 +175,8 @@ export class CollectionDockingView extends CollectionSubView() { @undoBatch @action public static AddSplit(document: Doc, pullSide: string, stack?: any, panelName?: string) { - if (document._viewType === CollectionViewType.Docking) return CurrentUserUtils.openDashboard(document); - + if (document._viewType === CollectionViewType.Docking) return DashboardView.openDashboard(document); + if (!CollectionDockingView.Instance) return false; const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === document); if (tab) { tab.header.parent.setActiveContentItem(tab.contentItem); @@ -193,35 +195,37 @@ export class CollectionDockingView extends CollectionSubView() { const newItem = glayRoot.layoutManager.createContentItem({ type: 'stack', content: [docContentConfig] }, instance._goldenLayout); newItem.callDownwards('_$init'); return newItem; - } - if (glayRoot.contentItems.length === 0) { // if no rows / columns + }; + if (glayRoot.contentItems.length === 0) { + // if no rows / columns glayRoot.addChild(newContentItem()); } else if (glayRoot.contentItems[0].isStack) { glayRoot.contentItems[0].addChild(docContentConfig); - } else if ( - glayRoot.contentItems.length === 1 && - glayRoot.contentItems[0].contentItems.length === 1 && - glayRoot.contentItems[0].contentItems[0].contentItems.length === 0) { + } else if (glayRoot.contentItems.length === 1 && glayRoot.contentItems[0].contentItems.length === 1 && glayRoot.contentItems[0].contentItems[0].contentItems.length === 0) { glayRoot.contentItems[0].contentItems[0].addChild(docContentConfig); - } - else if (instance._goldenLayout.root.contentItems[0].isRow) { // if row + } else if (instance._goldenLayout.root.contentItems[0].isRow) { + // if row switch (pullSide) { default: - case "right": glayRoot.contentItems[0].addChild(newContentItem()); break; - case "left": glayRoot.contentItems[0].addChild(newContentItem(), 0); break; - case "top": - case "bottom": + case 'right': + glayRoot.contentItems[0].addChild(newContentItem()); + break; + case 'left': + glayRoot.contentItems[0].addChild(newContentItem(), 0); + break; + case 'top': + case 'bottom': // if not going in a row layout, must add already existing content into column const rowlayout = glayRoot.contentItems[0]; - const newColumn = rowlayout.layoutManager.createContentItem({ type: "column" }, instance._goldenLayout); + const newColumn = rowlayout.layoutManager.createContentItem({ type: 'column' }, instance._goldenLayout); const newItem = newContentItem(); instance._goldenLayout.saveScrollTops(rowlayout.element); rowlayout.parent.replaceChild(rowlayout, newColumn); - if (pullSide === "top") { + if (pullSide === 'top') { newColumn.addChild(rowlayout, undefined, true); newColumn.addChild(newItem, 0, true); - } else if (pullSide === "bottom") { + } else if (pullSide === 'bottom') { newColumn.addChild(newItem, undefined, true); newColumn.addChild(rowlayout, 0, true); } @@ -230,21 +234,26 @@ export class CollectionDockingView extends CollectionSubView() { rowlayout.config.height = 50; newItem.config.height = 50; } - } else {// if (instance._goldenLayout.root.contentItems[0].isColumn) { // if column + } else { + // if (instance._goldenLayout.root.contentItems[0].isColumn) { // if column switch (pullSide) { - case "top": glayRoot.contentItems[0].addChild(newContentItem(), 0); break; - case "bottom": glayRoot.contentItems[0].addChild(newContentItem()); break; - case "left": - case "right": + case 'top': + glayRoot.contentItems[0].addChild(newContentItem(), 0); + break; + case 'bottom': + glayRoot.contentItems[0].addChild(newContentItem()); + break; + case 'left': + case 'right': default: // if not going in a row layout, must add already existing content into column const collayout = glayRoot.contentItems[0]; - const newRow = collayout.layoutManager.createContentItem({ type: "row" }, instance._goldenLayout); + const newRow = collayout.layoutManager.createContentItem({ type: 'row' }, instance._goldenLayout); const newItem = newContentItem(); instance._goldenLayout.saveScrollTops(collayout.element); collayout.parent.replaceChild(collayout, newRow); - if (pullSide === "left") { + if (pullSide === 'left') { newRow.addChild(collayout, undefined, true); newRow.addChild(newItem, 0, true); } else { @@ -276,7 +285,7 @@ export class CollectionDockingView extends CollectionSubView() { const config = StrCast(this.props.Document.dockingConfig); if (config) { const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g); - const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", "")) ?? []; + const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? []; await Promise.all(docids.map(id => DocServer.GetRefField(id))); if (this._goldenLayout) { @@ -287,12 +296,12 @@ export class CollectionDockingView extends CollectionSubView() { this._goldenLayout.unbind('tabCreated', this.tabCreated); this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed); this._goldenLayout.unbind('stackCreated', this.stackCreated); - } catch (e) { } + } catch (e) {} } this.tabMap.clear(); this._goldenLayout.destroy(); } - const glay = this._goldenLayout = new GoldenLayout(JSON.parse(config)); + const glay = (this._goldenLayout = new GoldenLayout(JSON.parse(config))); glay.on('tabCreated', this.tabCreated); glay.on('tabDestroyed', this.tabDestroyed); glay.on('stackCreated', this.stackCreated); @@ -303,46 +312,52 @@ export class CollectionDockingView extends CollectionSubView() { glay.root.layoutManager.on('dragStart', this.tabDragStart); glay.root.layoutManager.on('activeContentItemChanged', this.stateChanged); } - } + }; componentDidMount: () => void = () => { if (this._containerRef.current) { - this._lightboxReactionDisposer = reaction(() => LightboxView.LightboxDoc, doc => setTimeout(() => !doc && this.onResize(undefined))); + this._lightboxReactionDisposer = reaction( + () => LightboxView.LightboxDoc, + doc => setTimeout(() => !doc && this.onResize(undefined)) + ); new _global.ResizeObserver(this.onResize).observe(this._containerRef.current); - this._reactionDisposer = reaction(() => StrCast(this.props.Document.dockingConfig), + this._reactionDisposer = reaction( + () => StrCast(this.props.Document.dockingConfig), config => { - if (!this._goldenLayout || this._ignoreStateChange !== config) { // bcz: TODO! really need to diff config with ignoreStateChange and modify the current goldenLayout instead of building a new one. + if (!this._goldenLayout || this._ignoreStateChange !== config) { + // bcz: TODO! really need to diff config with ignoreStateChange and modify the current goldenLayout instead of building a new one. this.setupGoldenLayout(); } - this._ignoreStateChange = ""; - }); + this._ignoreStateChange = ''; + } + ); setTimeout(this.setupGoldenLayout); //window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window } - } + }; componentWillUnmount: () => void = () => { try { this._goldenLayout.unbind('stackCreated', this.stackCreated); this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed); - } catch (e) { } + } catch (e) {} this._goldenLayout?.destroy(); window.removeEventListener('resize', this.onResize); this._reactionDisposer?.(); this._lightboxReactionDisposer?.(); - } + }; @action onResize = (event: any) => { const cur = this._containerRef.current; // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed !LightboxView.LightboxDoc && cur && this._goldenLayout?.updateSize(cur.getBoundingClientRect().width, cur.getBoundingClientRect().height); - } + }; @action onPointerUp = (e: MouseEvent): void => { - window.removeEventListener("pointerup", this.onPointerUp); + window.removeEventListener('pointerup', this.onPointerUp); const flush = this._flush; this._flush = undefined; if (flush) { @@ -350,75 +365,71 @@ export class CollectionDockingView extends CollectionSubView() { if (!this.stateChanged()) flush.cancel(); else flush.end(); } - } + }; @action onPointerDown = (e: React.PointerEvent): void => { let hitFlyout = false; for (let par = e.target as any; !hitFlyout && par; par = par.parentElement) { - hitFlyout = (par.className === "dockingViewButtonSelector"); + hitFlyout = par.className === 'dockingViewButtonSelector'; } if (!hitFlyout) { const htmlTarget = e.target as HTMLElement; - window.addEventListener("mouseup", this.onPointerUp); - if (!htmlTarget.closest("*.lm_content") && (htmlTarget.closest("*.lm_tab") || htmlTarget.closest("*.lm_stack"))) { - const className = typeof htmlTarget.className === "string" ? htmlTarget.className : ""; - if (!className.includes("lm_close") && !className.includes("lm_maximise")) { - this._flush = UndoManager.StartBatch("golden layout edit"); + window.addEventListener('mouseup', this.onPointerUp); + if (!htmlTarget.closest('*.lm_content') && (htmlTarget.closest('*.lm_tab') || htmlTarget.closest('*.lm_stack'))) { + const className = typeof htmlTarget.className === 'string' ? htmlTarget.className : ''; + if (!className.includes('lm_close') && !className.includes('lm_maximise')) { + this._flush = UndoManager.StartBatch('golden layout edit'); } } } - if (!e.nativeEvent.cancelBubble && !InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE) && - ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.ActiveTool)) { + if (!InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) { e.stopPropagation(); } - } + }; public CaptureThumbnail() { const content = this.props.DocumentView?.()?.ContentDiv; if (content) { - const _width = Number(getComputedStyle(content).width.replace("px","")); - const _height = Number(getComputedStyle(content).height.replace("px","")); - return CollectionFreeFormView.UpdateIcon( - this.layoutDoc[Id] + "-icon" + (new Date()).getTime(), - content, - _width, _height, - _width, _height, 0, 1, true, this.layoutDoc[Id] + "-icon", - (iconFile, _nativeWidth, _nativeHeight) => { - const img = Docs.Create.ImageDocument(new ImageField(iconFile), { title: this.rootDoc.title+"-icon", _width, _height, _nativeWidth, _nativeHeight}); - const proto = Cast(img.proto, Doc, null)!; - proto["data-nativeWidth"] = _width; - proto["data-nativeHeight"] = _height; - this.dataDoc.thumb = img; - }); + const _width = Number(getComputedStyle(content).width.replace('px', '')); + const _height = Number(getComputedStyle(content).height.replace('px', '')); + return CollectionFreeFormView.UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', (iconFile, _nativeWidth, _nativeHeight) => { + const img = Docs.Create.ImageDocument(new ImageField(iconFile), { title: this.rootDoc.title + '-icon', _width, _height, _nativeWidth, _nativeHeight }); + const proto = Cast(img.proto, Doc, null)!; + proto['data-nativeWidth'] = _width; + proto['data-nativeHeight'] = _height; + this.dataDoc.thumb = img; + }); } - } - public static async TakeSnapshot(doc: Doc|undefined, clone = false) { + public static async TakeSnapshot(doc: Doc | undefined, clone = false) { if (!doc) return undefined; let json = StrCast(doc.dockingConfig); if (clone) { const cloned = await Doc.MakeClone(doc); - Array.from(cloned.map.entries()).map(entry => json = json.replace(entry[0], entry[1][Id])); + Array.from(cloned.map.entries()).map(entry => (json = json.replace(entry[0], entry[1][Id]))); Doc.GetProto(cloned.clone).dockingConfig = json; - return CurrentUserUtils.openDashboard(cloned.clone); + return DashboardView.openDashboard(cloned.clone); } const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g); - const origtabids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", "")) || []; - const origtabs = origtabids.map(id => DocServer.GetCachedRefField(id)).filter(f => f).map(f => f as Doc); + const origtabids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) || []; + const origtabs = origtabids + .map(id => DocServer.GetCachedRefField(id)) + .filter(f => f) + .map(f => f as Doc); const newtabs = origtabs.map(origtab => { const origtabdocs = DocListCast(origtab.data); const newtab = origtabdocs.length ? Doc.MakeCopy(origtab, true, undefined, true) : Doc.MakeAlias(origtab); const newtabdocs = origtabdocs.map(origtabdoc => Doc.MakeAlias(origtabdoc)); if (newtabdocs.length) { Doc.GetProto(newtab).data = new List<Doc>(newtabdocs); - newtabdocs.forEach(ntab => ntab.context = newtab); + newtabdocs.forEach(ntab => (ntab.context = newtab)); } json = json.replace(origtab[Id], newtab[Id]); return newtab; }); const copy = Docs.Create.DockDocument(newtabs, json, { title: incrementTitleCopy(StrCast(doc.title)) }); - return CurrentUserUtils.openDashboard(await copy); + return DashboardView.openDashboard(await copy); } @action @@ -426,87 +437,126 @@ export class CollectionDockingView extends CollectionSubView() { this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig()); const json = JSON.stringify(this._goldenLayout.toConfig()); const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g); - const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", "")); - const docs = !docids ? [] : docids.map(id => DocServer.GetCachedRefField(id)).filter(f => f).map(f => f as Doc); + const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')); + const docs = !docids + ? [] + : docids + .map(id => DocServer.GetCachedRefField(id)) + .filter(f => f) + .map(f => f as Doc); const changesMade = this.props.Document.dockcingConfig !== json; if (changesMade && !this._flush) { UndoManager.RunInBatch(() => { this.props.Document.dockingConfig = json; this.props.Document.data = new List<Doc>(docs); - }, "state changed"); + }, 'state changed'); } return changesMade; - } + }; tabDestroyed = (tab: any) => { - if(tab.DashDoc?.type !== DocumentType.KVP) { - Doc.AddDocToList(CurrentUserUtils.MyHeaderBar, "data", tab.DashDoc); - Doc.AddDocToList(CurrentUserUtils.MyRecentlyClosed, "data", tab.DashDoc, undefined, true, true); + if (tab.DashDoc?.type !== DocumentType.KVP) { + Doc.AddDocToList(Doc.MyHeaderBar, 'data', tab.DashDoc); + Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', tab.DashDoc, undefined, true, true); } - const dview = CollectionDockingView.Instance.props.Document; - const fieldKey = CollectionDockingView.Instance.props.fieldKey; - Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc); - this.tabMap.delete(tab); - tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.()); - tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele)); - this.stateChanged(); - } + if (CollectionDockingView.Instance) { + const dview = CollectionDockingView.Instance.props.Document; + const fieldKey = CollectionDockingView.Instance.props.fieldKey; + Doc.RemoveDocFromList(dview, fieldKey, tab.DashDoc); + this.tabMap.delete(tab); + tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.()); + tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele)); + setTimeout(this.stateChanged); + } + }; tabCreated = (tab: any) => { this.tabMap.add(tab); - tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content) - } + tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content) + }; stackCreated = (stack: any) => { stack.header?.element.on('mousedown', (e: any) => { - const dashboard = CurrentUserUtils.ActiveDashboard; + const dashboard = Doc.ActiveDashboard; if (dashboard && e.target === stack.header?.element[0] && e.button === 2) { - dashboard["pane-count"] = NumCast(dashboard["pane-count"]) + 1; + dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1; const docToAdd = Docs.Create.FreeformDocument([], { - _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _backgroundGridShow: true, _fitWidth: true, title: `Untitled Tab ${NumCast(dashboard["pane-count"])}`, + _width: this.props.PanelWidth(), + _height: this.props.PanelHeight(), + _backgroundGridShow: true, + _fitWidth: true, + title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`, }); this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd); - CollectionDockingView.AddSplit(docToAdd, "", stack); + CollectionDockingView.AddSplit(docToAdd, '', stack); } }); - stack.header?.controlsContainer.find('.lm_close') //get the close icon + stack.header?.controlsContainer + .find('.lm_close') //get the close icon .off('click') //unbind the current click handler - .click(action(() => { - //if (confirm('really close this?')) { - if (!stack.parent.parent.isRoot || stack.parent.contentItems.length > 1) { - stack.remove(); - } else { - alert('cant delete the last stack'); - } - })); + .click( + action(() => { + //if (confirm('really close this?')) { + if (!stack.parent.parent.isRoot || stack.parent.contentItems.length > 1) { + stack.remove(); + } else { + alert('cant delete the last stack'); + } + }) + ); - stack.header?.controlsContainer.find('.lm_maximise') //get the close icon + stack.header?.controlsContainer + .find('.lm_maximise') //get the close icon .click(() => setTimeout(this.stateChanged)); - stack.header?.controlsContainer.find('.lm_popout') //get the popout icon + stack.header?.controlsContainer + .find('.lm_popout') //get the popout icon .off('click') //unbind the current click handler - .click(action(() => { - // stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size - const dashboard = CurrentUserUtils.ActiveDashboard; - if (dashboard) { - dashboard["pane-count"] = NumCast(dashboard["pane-count"]) + 1; - const docToAdd = Docs.Create.FreeformDocument([], { - _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, _backgroundGridShow: true, title: `Untitled Tab ${NumCast(dashboard["pane-count"])}` - }); - this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd); - CollectionDockingView.AddSplit(docToAdd, "", stack); - } - })); - } + .click( + action(() => { + // stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size + const dashboard = Doc.ActiveDashboard; + if (dashboard) { + dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1; + const docToAdd = Docs.Create.FreeformDocument([], { + _width: this.props.PanelWidth(), + _height: this.props.PanelHeight(), + _fitWidth: true, + _backgroundGridShow: true, + title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`, + }); + this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd); + CollectionDockingView.AddSplit(docToAdd, '', stack); + } + }) + ); + }; render() { return <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} ref={this._containerRef} />; } } -ScriptingGlobals.add(function openInLightbox(doc: any) { LightboxView.AddDocTab(doc, "lightbox"); }, - "opens up document in a lightbox", "(doc: any)"); -ScriptingGlobals.add(function openOnRight(doc: any) { return CollectionDockingView.AddSplit(doc, "right"); }, - "opens up document in tab on right side of the screen", "(doc: any)"); -ScriptingGlobals.add(function openInOverlay(doc: any) { return Doc.AddDocToList(CurrentUserUtils.MyOverlayDocs, undefined, doc); }, - "opens up document in screen overlay layer", "(doc: any)"); -ScriptingGlobals.add(function useRightSplit(doc: any, shiftKey?: boolean) { CollectionDockingView.ReplaceTab(doc, "right", undefined, shiftKey); });
\ No newline at end of file +ScriptingGlobals.add( + function openInLightbox(doc: any) { + LightboxView.AddDocTab(doc, 'lightbox'); + }, + 'opens up document in a lightbox', + '(doc: any)' +); +ScriptingGlobals.add( + function openOnRight(doc: any) { + return CollectionDockingView.AddSplit(doc, 'right'); + }, + 'opens up document in tab on right side of the screen', + '(doc: any)' +); +ScriptingGlobals.add( + function openInOverlay(doc: any) { + return Doc.AddDocToList(Doc.MyOverlayDocs, undefined, doc); + }, + 'opens up document in screen overlay layer', + '(doc: any)' +); +ScriptingGlobals.add(function useRightSplit(doc: any, shiftKey?: boolean) { + CollectionDockingView.ReplaceTab(doc, 'right', undefined, shiftKey); +}); |
