diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/ContextMenu.scss | 13 | ||||
-rw-r--r-- | src/client/views/ContextMenu.tsx | 3 | ||||
-rw-r--r-- | src/client/views/ContextMenuItem.tsx | 9 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 20 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 9 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 26 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 181 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 13 | ||||
-rw-r--r-- | src/server/index.ts | 5 |
9 files changed, 174 insertions, 105 deletions
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index b7fd60ffb..ea40c8e99 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -3,16 +3,15 @@ display: flex; z-index: 1000; box-shadow: #AAAAAA .2vw .2vw .4vw; - flex-direction: column; //E - // border-radius: 20px; + flex-direction: column; } .contextMenu-item { - width: auto; //10vw - height: auto; //4vh - background: #F0F8FF; // background: #DDDDDD; + width: auto; + height: auto; + background: #F0F8FF; display: flex; - justify-content: left; //center + justify-content: left; align-items: center; -webkit-touch-callout: none; -webkit-user-select: none; @@ -32,7 +31,7 @@ .contextMenu-item:hover { transition: all .1s; - background: #B0E0E6; // background: #AAAAAA + background: #B0E0E6; } .contextMenu-description { diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index ed35021d3..fcb934860 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -3,9 +3,6 @@ import { ContextMenuItem, ContextMenuProps } from "./ContextMenuItem"; import { observable, action } from "mobx"; import { observer } from "mobx-react"; import "./ContextMenu.scss" -// import { library } from '@fortawesome/fontawesome-svg-core' -// import { faIgloo } from '@fortawesome/free-solid-svg-icons' -// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' @observer export class ContextMenu extends React.Component { diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 8f00f8b3d..723606dcf 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -6,6 +6,15 @@ export interface ContextMenuProps { event: (e: React.MouseEvent<HTMLDivElement>) => void; } +export interface SubmenuProps { + description: string; + subitems: ContextMenuProps[]; +} + +export interface ContextMenuItemProps { + type: ContextMenuProps | SubmenuProps +} + export class ContextMenuItem extends React.Component<ContextMenuProps> { render() { return ( diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 17dda899d..23438c91f 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -66,17 +66,19 @@ Documents.initProtos(() => { mainContainer.GetAsync(KeyStore.ActiveFrame, field => mainfreeform = field as Document); } else { - mainContainer = Documents.DockDocument(JSON.stringify({ content: [{ type: 'row', content: [] }] }), { title: "main container" }, mainDocId); - Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainContainer.ToJson())) + // mainContainer = Documents.DockDocument(JSON.stringify({ content: [{ type: 'row', content: [] }] }), { title: "main container" }, mainDocId); + // Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainContainer.ToJson())) - setTimeout(() => { - mainfreeform = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" }); - Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainfreeform.ToJson())); + // setTimeout(() => { + // mainfreeform = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" }); + // Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainfreeform.ToJson())); - var docs = [mainfreeform].map(doc => CollectionDockingView.makeDocumentConfig(doc)); - mainContainer.SetText(KeyStore.Data, JSON.stringify({ content: [{ type: 'row', content: docs }] })); - mainContainer.Set(KeyStore.ActiveFrame, mainfreeform); - }, 0); + // var docs = [mainfreeform].map(doc => CollectionDockingView.makeDocumentConfig(doc)); + // mainContainer.SetText(KeyStore.Data, JSON.stringify({ content: [{ type: 'row', content: docs }] })); + // mainContainer.Set(KeyStore.ActiveFrame, mainfreeform); + // }, 0); + mainContainer = Documents.FreeformDocument([], {}); + mainfreeform = mainContainer; } let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {})) diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 22b5989a0..4beb0aea1 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -181,13 +181,6 @@ export class CollectionSchemaView extends CollectionViewBase { } } - //REPLACE THIS WITH CAPABILITIES SPECIFIC TO THIS TYPE OF NODE - collectionCapability = (e: React.MouseEvent): void => { - } - - specificContextMenu = (e: React.MouseEvent): void => { - ContextMenu.Instance.addItem({ description: "Collection Capability", event: this.collectionCapability }); - } @action setScaling = (r: any) => { const children = this.props.Document.GetList<Document>(this.props.fieldKey, []); @@ -227,7 +220,7 @@ export class CollectionSchemaView extends CollectionViewBase { let handle = !this.props.active() ? (null) : ( <div style={{ position: "absolute", height: "37px", width: "20px", zIndex: 20, right: 0, top: 0, background: "Black" }} onPointerDown={this.onExpanderDown} />); return ( - <div onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} ref={this._mainCont} className="collectionSchemaView-container" style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} > + <div onPointerDown={this.onPointerDown} ref={this._mainCont} className="collectionSchemaView-container" style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} > <Measure onResize={action((r: any) => { this._dividerX = r.entry.width; this._panelHeight = r.entry.height; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 03e1f1fa4..a7db07a42 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -87,27 +87,43 @@ export class CollectionView extends React.Component<CollectionViewProps> { Document.SetData(KeyStore.ViewType, type, NumberField); } + specificContextMenu = (e: React.MouseEvent): void => { + ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) + ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) + ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) + ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) + } + render() { let viewType = this.collectionViewType; + let subView: JSX.Element; switch (viewType) { case CollectionViewType.Freeform: - return (<CollectionFreeFormView {...this.props} + subView = (<CollectionFreeFormView {...this.props} addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active} CollectionView={this} />) + break; case CollectionViewType.Schema: - return (<CollectionSchemaView {...this.props} + subView = (<CollectionSchemaView {...this.props} addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active} CollectionView={this} />) + break; case CollectionViewType.Docking: - return (<CollectionDockingView {...this.props} + subView = (<CollectionDockingView {...this.props} addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active} CollectionView={this} />) + break; case CollectionViewType.Tree: - return (<CollectionTreeView {...this.props} + subView = (<CollectionTreeView {...this.props} addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active} CollectionView={this} />) + break; default: - return <div></div> + subView = <div></div> + break; } + return (<div onContextMenu={this.specificContextMenu}> + {subView} + </div>) } }
\ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4c302ed87..a14239e94 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -18,17 +18,15 @@ import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; import "./DocumentView.scss"; import React = require("react"); -const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? +const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? export interface DocumentViewProps { ContainingCollectionView: Opt<CollectionView>; - Document: Document; AddDocument?: (doc: Document) => void; RemoveDocument?: (doc: Document) => boolean; ScreenToLocalTransform: () => Transform; - isTopMost: boolean; - //tfs: This shouldn't be necessary I don't think + isTopMost: boolean; //tfs: This shouldn't be necessary I don't think ContentScaling: () => number; PanelWidth: () => number; PanelHeight: () => number; @@ -53,6 +51,7 @@ Example usage of this function: ) } */ + export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { let Keys: { [name: string]: any } = {} let Fields: { [name: string]: any } = {} @@ -75,23 +74,28 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { return args; } -@observer -export class DocumentView extends React.Component<DocumentViewProps> { - +@observer export class DocumentView extends React.Component<DocumentViewProps> { private _mainCont = React.createRef<HTMLDivElement>(); private _documentBindings: any = null; private _contextMenuCanOpen = false; private _downX: number = 0; private _downY: number = 0; - - @computed get active(): boolean { return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || this.props.ContainingCollectionView.active(); } - @computed get topMost(): boolean { return !this.props.ContainingCollectionView || this.props.ContainingCollectionView.collectionViewType == CollectionViewType.Docking; } - @computed get layout(): string { return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); } - @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); } - @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); } - + @computed get active(): boolean { + return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || this.props.ContainingCollectionView.active(); + } + @computed get topMost(): boolean { + return !this.props.ContainingCollectionView || this.props.ContainingCollectionView.collectionViewType == CollectionViewType.Docking; + } + @computed get layout(): string { + return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); + } + @computed get layoutKeys(): Key[] { + return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); + } + @computed get layoutFields(): Key[] { + return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); + } screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect(); - onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; @@ -112,7 +116,6 @@ export class DocumentView extends React.Component<DocumentViewProps> { } } } - onPointerMove = (e: PointerEvent): void => { if (e.cancelBubble) { this._contextMenuCanOpen = false; @@ -122,23 +125,29 @@ export class DocumentView extends React.Component<DocumentViewProps> { this._contextMenuCanOpen = false; if (this._mainCont.current != null && !this.topMost) { this._contextMenuCanOpen = false; - const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - let dragData: { [id: string]: any } = {}; + const [left, + top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + let dragData: { + [id: string]: any + } + = {} + ; dragData["documentView"] = this; dragData["xOffset"] = e.x - left; dragData["yOffset"] = e.y - top; DragManager.StartDrag(this._mainCont.current, dragData, { handlers: { - dragComplete: action((e: DragManager.DragCompleteEvent) => { }), - }, - hideSource: true - }) + dragComplete: action((e: DragManager.DragCompleteEvent) => { } + ), + } + , hideSource: true + } + ) } } e.stopPropagation(); e.preventDefault(); } - onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove) document.removeEventListener("pointerup", this.onPointerUp) @@ -147,7 +156,6 @@ export class DocumentView extends React.Component<DocumentViewProps> { SelectionManager.SelectDoc(this, e.ctrlKey); } } - deleteClicked = (e: React.MouseEvent): void => { if (this.props.RemoveDocument) { this.props.RemoveDocument(this.props.Document); @@ -156,93 +164,124 @@ export class DocumentView extends React.Component<DocumentViewProps> { fullScreenClicked = (e: React.MouseEvent): void => { CollectionDockingView.Instance.OpenFullScreen(this.props.Document); ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked }); + ContextMenu.Instance.addItem({ + description: "Close Full Screen", event: this.closeFullScreenClicked + } + ); ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) } closeFullScreenClicked = (e: React.MouseEvent): void => { CollectionDockingView.Instance.CloseFullScreen(); ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) + ContextMenu.Instance.addItem({ + description: "Full Screen", event: this.fullScreenClicked + }) ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) } - - @action - onContextMenu = (e: React.MouseEvent): void => { + @action onContextMenu = (e: React.MouseEvent): void => { e.preventDefault() e.stopPropagation(); if (!SelectionManager.IsSelected(this) || !this._contextMenuCanOpen) { return; } - if (this.topMost) { - ContextMenu.Instance.clearItems() - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) + ContextMenu.Instance.addItem({ + description: "Full Screen", event: this.fullScreenClicked + }) ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) } else { // DocumentViews should stop propagation of this event - e.stopPropagation(); - - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) }) - ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }) - // ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) - // ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) - // ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) - // ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) + ContextMenu.Instance.addItem({ + description: "Full Screen", event: this.fullScreenClicked + } + ) + ContextMenu.Instance.addItem({ + description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) + } + ) + ContextMenu.Instance.addItem({ + description: "Delete", event: this.deleteClicked + } + ) ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) SelectionManager.SelectDoc(this, e.ctrlKey); } } - @computed get mainContent() { var val = this.props.Document.Id; - return <JsxParser - components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebView }} - bindings={this._documentBindings} - jsx={this.layout} - showWarnings={true} - onError={(test: any) => { console.log(test) }} + return <JsxParser components={ + { + FormattedTextBox, + ImageBox, + CollectionFreeFormView, + CollectionDockingView, + CollectionSchemaView, + CollectionView, + WebView + } + } + bindings={ + this._documentBindings + } + jsx={ + this.layout + } + showWarnings={ + true + } + onError={ + (test: any) => { + console.log(test) + } + } /> } render() { - if (!this.props.Document) - return <div></div> + if (!this.props.Document) return <div></div> let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); if (!lkeys || lkeys === "<Waiting>") { return <p>Error loading layout keys</p>; } this._documentBindings = { ...this.props, - isSelected: () => SelectionManager.IsSelected(this), - select: (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed) - }; + isSelected: () => SelectionManager.IsSelected(this), select: (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed) + } + ; for (const key of this.layoutKeys) { - this._documentBindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data + this._documentBindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data } for (const key of this.layoutFields) { let field = this.props.Document.Get(key); this._documentBindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field; } this._documentBindings.bindings = this._documentBindings; - var scaling = this.props.ContentScaling(); var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); - return ( - <div className="documentView-node" ref={this._mainCont} - style={{ - width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%", - height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%", - transformOrigin: "left top", - transform: `scale(${scaling},${scaling})` - }} - onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown} - > - {this.mainContent} - </div> - ) + return (<div className="documentView-node" ref={ + this._mainCont + } + style={ + { + width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%", height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%", transformOrigin: "left top", transform: `scale($ { + scaling + } + , $ { + scaling + } + )` + } + } + onContextMenu={ + this.onContextMenu + } + onPointerDown={ + this.onPointerDown + } + > { + this.mainContent + } + </div>) } -} +}
\ No newline at end of file diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index d0dd9e91f..8b3deeb8b 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -119,6 +119,19 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { specificContextMenu = (e: React.MouseEvent): void => { ContextMenu.Instance.addItem({ description: "Text Capability", event: this.textCapability }); + // ContextMenu.Instance.addItem({ + // description: "Submenu", + // items: [ + // { + // description: "item 1", event: + // }, + // { + // description: "item 2", event: + // } + // ] + // }) + // e.stopPropagation() + } onPointerWheel = (e: React.WheelEvent): void => { diff --git a/src/server/index.ts b/src/server/index.ts index eb0527ee7..84acb72cb 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -125,7 +125,6 @@ function deleteAll() { function barReceived(guid: String) { clients[guid.toString()] = new Client(guid.toString()); - // Database.Instance.print() } function addDocument(document: Document) { @@ -148,7 +147,9 @@ function getFields([ids, callback]: [string[], (result: any) => void]) { } function setField(socket: Socket, newValue: Transferable) { - Database.Instance.update(newValue._id, newValue) + let val = { ...newValue }; + delete val._id; + Database.Instance.update(newValue._id, val) socket.broadcast.emit(MessageStore.SetField.Message, newValue) } |