diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/Server.ts | 106 | ||||
| -rw-r--r-- | src/client/SocketStub.ts | 28 | ||||
| -rw-r--r-- | src/client/documents/Documents.ts | 51 | ||||
| -rw-r--r-- | src/client/util/Scripting.ts | 2 | ||||
| -rw-r--r-- | src/client/views/Main.tsx | 132 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 28 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionFreeFormView.tsx | 65 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionViewBase.tsx | 27 | ||||
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 23 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 63 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 2 |
14 files changed, 351 insertions, 186 deletions
diff --git a/src/client/Server.ts b/src/client/Server.ts index a08fc2e87..2077c0c57 100644 --- a/src/client/Server.ts +++ b/src/client/Server.ts @@ -1,54 +1,104 @@ -import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "../fields/Field" -import { Key, KeyStore } from "../fields/Key" -import { ObservableMap, action } from "mobx"; +import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue, Opt } from "../fields/Field" +import { Key } from "../fields/Key" +import { KeyStore } from "../fields/KeyStore" +import { ObservableMap, action, reaction, when } from "mobx"; import { Document } from "../fields/Document" import { SocketStub } from "./SocketStub"; import * as OpenSocket from 'socket.io-client'; import { Utils } from "./../Utils"; -import { MessageStore } from "./../server/Message"; +import { MessageStore, Types } from "./../server/Message"; export class Server { - private static ClientFieldsCached: ObservableMap<FIELD_ID, Field | FIELD_WAITING> = new ObservableMap(); - static Socket: SocketIOClient.Socket = OpenSocket("http://localhost:1234") + public static ClientFieldsCached: ObservableMap<FIELD_ID, Field | FIELD_WAITING> = new ObservableMap(); + static Socket: SocketIOClient.Socket = OpenSocket("http://localhost:1234"); static GUID: string = Utils.GenerateGuid() + // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). // Call this is from within a reaction and test whether the return value is FieldWaiting. // 'hackTimeout' is here temporarily for simplicity when debugging things. - public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { - if (!this.ClientFieldsCached.get(fieldid)) { + public static GetField(fieldid: FIELD_ID, callback: (field: Opt<Field>) => void = (f) => { }, doc?: Document, key?: Key, hackTimeout: number = -1) { + let cached = this.ClientFieldsCached.get(fieldid); + if (!cached) { this.ClientFieldsCached.set(fieldid, FieldWaiting); - //simulating a server call with a registered callback action - SocketStub.SEND_FIELD_REQUEST(fieldid, - action((field: Field) => callback(Server.cacheField(field)))); - } else if (this.ClientFieldsCached.get(fieldid) != FieldWaiting) { - callback(this.ClientFieldsCached.get(fieldid) as Field); + SocketStub.SEND_FIELD_REQUEST(fieldid, action((field: Field | undefined) => { + let cached = this.ClientFieldsCached.get(fieldid); + if (cached != FieldWaiting) + callback(cached); + else { + if (field) { + this.ClientFieldsCached.set(fieldid, field); + } else { + this.ClientFieldsCached.delete(fieldid) + } + callback(field) + } + })); + } else if (cached != FieldWaiting) { + callback(cached); + } else { + reaction(() => { + return this.ClientFieldsCached.get(fieldid); + }, (field, reaction) => { + if (field !== "<Waiting>") { + callback(field) + reaction.dispose() + } + }) } - return this.ClientFieldsCached.get(fieldid); + return cached; + } + + public static GetFields(fieldIds: FIELD_ID[], callback: (fields: { [id: string]: Field }) => any) { + SocketStub.SEND_FIELDS_REQUEST(fieldIds, (fields) => { + for (let key in fields) { + let field = fields[key]; + if (!this.ClientFieldsCached.has(field.Id)) { + this.ClientFieldsCached.set(field.Id, field) + } + } + callback(fields) + }); } static times = 0; // hack for testing public static GetDocumentField(doc: Document, key: Key) { - var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500; - + // let keyId: string = element[0] + // let valueId: string = element[1] + // Server.GetField(keyId, (key: Field) => { + // if (key instanceof Key) { + // Server.GetField(valueId, (field: Field) => { + // console.log(field) + // doc.Set(key as Key, field) + // }) + // } + // else { + // console.log("how did you get a key that isnt a key wtf") + // } + // }) return this.GetField(doc._proxies.get(key.Id), - action((fieldfromserver: Field) => { - doc._proxies.delete(key.Id); - doc.fields.set(key, fieldfromserver); - }) - , hackTimeout); + action((fieldfromserver: Opt<Field>) => { + if (fieldfromserver) { + doc.fields.set(key.Id, { key, field: fieldfromserver }); + } + }), doc, key); } public static AddDocument(document: Document) { SocketStub.SEND_ADD_DOCUMENT(document); } public static AddDocumentField(doc: Document, key: Key, value: Field) { + console.log("Add doc field " + doc.Title + " " + key.Name + " fid " + value.Id + " " + value); SocketStub.SEND_ADD_DOCUMENT_FIELD(doc, key, value); } public static DeleteDocumentField(doc: Document, key: Key) { SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key); } + public static UpdateField(field: Field) { + if (!this.ClientFieldsCached.has(field.Id)) { + this.ClientFieldsCached.set(field.Id, field) + } SocketStub.SEND_SET_FIELD(field); } @@ -66,6 +116,18 @@ export class Server { } return this.ClientFieldsCached.get(clientField.Id) as Field; } + + @action + static updateField(field: { _id: string, data: any, type: Types }) { + if (Server.ClientFieldsCached.has(field._id)) { + var f = Server.ClientFieldsCached.get(field._id); + if (f && f != FieldWaiting) { + f.UpdateFromServer(field.data); + f.init(() => { }); + } + } + } } -Server.Socket.on(MessageStore.Foo.Message, Server.connected);
\ No newline at end of file +Server.Socket.on(MessageStore.Foo.Message, Server.connected); +Server.Socket.on(MessageStore.SetField.Message, Server.updateField);
\ No newline at end of file diff --git a/src/client/SocketStub.ts b/src/client/SocketStub.ts index 03c0131ba..2bddf4e97 100644 --- a/src/client/SocketStub.ts +++ b/src/client/SocketStub.ts @@ -1,10 +1,12 @@ -import { Field, FIELD_ID } from "../fields/Field" -import { Key, KeyStore } from "../fields/Key" +import { Field, FIELD_ID, Opt } from "../fields/Field" +import { Key } from "../fields/Key" +import { KeyStore } from "../fields/KeyStore" import { ObservableMap, action } from "mobx"; import { Document } from "../fields/Document" import { MessageStore, SetFieldArgs, GetFieldArgs, DocumentTransfer, Types } from "../server/Message"; import { Utils } from "../Utils"; import { Server } from "./Server"; +import { ServerUtils } from "../server/ServerUtil"; export class SocketStub { @@ -29,16 +31,32 @@ export class SocketStub { // this.FieldStore.set(document.Id, new Document(document.Id)); // document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key.Id, (f as Field).Id)); + console.log("sending " + document.Title); Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(document.ToJson())) } - public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void) { + public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Opt<Field>) => void) { if (fieldid) { - let args: GetFieldArgs = new GetFieldArgs(fieldid) - Utils.EmitCallback(Server.Socket, MessageStore.GetField, args, (field: Field) => callback(field)) + Utils.EmitCallback(Server.Socket, MessageStore.GetField, fieldid, (field: any) => { + if (field) { + ServerUtils.FromJson(field).init(callback); + } else { + callback(undefined); + } + }) } } + public static SEND_FIELDS_REQUEST(fieldIds: FIELD_ID[], callback: (fields: { [key: string]: Field }) => any) { + Utils.EmitCallback(Server.Socket, MessageStore.GetFields, fieldIds, (fields: any[]) => { + let fieldMap: any = {}; + for (let field of fields) { + fieldMap[field._id] = ServerUtils.FromJson(field); + } + callback(fieldMap) + }); + } + public static SEND_ADD_DOCUMENT_FIELD(doc: Document, key: Key, value: Field) { // Send a serialized version of the field to the server along with the diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 460bf9b23..f779dcd03 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1,6 +1,6 @@ import { Document } from "../../fields/Document"; import { Server } from "../Server"; -import { KeyStore } from "../../fields/Key"; +import { KeyStore } from "../../fields/KeyStore"; import { TextField } from "../../fields/TextField"; import { NumberField } from "../../fields/NumberField"; import { ListField } from "../../fields/ListField"; @@ -21,20 +21,31 @@ interface DocumentOptions { } export namespace Documents { + export function initProtos(callback: () => void) { + Server.GetFields([collectionProtoId, textProtoId, imageProtoId, schemaProtoId, dockProtoId], (fields) => { + collectionProto = fields[collectionProtoId] as Document; + imageProto = fields[imageProtoId] as Document; + textProto = fields[textProtoId] as Document; + dockProto = fields[dockProtoId] as Document; + schemaProto = fields[schemaProtoId] as Document; + callback() + }); + } + function setupOptions(doc: Document, options: DocumentOptions): void { - if (options.x) { + if (options.x != undefined) { doc.SetData(KeyStore.X, options.x, NumberField); } - if (options.y) { + if (options.y != undefined) { doc.SetData(KeyStore.Y, options.y, NumberField); } - if (options.width) { + if (options.width != undefined) { doc.SetData(KeyStore.Width, options.width, NumberField); } - if (options.height) { + if (options.height != undefined) { doc.SetData(KeyStore.Height, options.height, NumberField); } - if (options.title) { + if (options.title != undefined) { doc.SetData(KeyStore.Title, options.title, TextField); } doc.SetData(KeyStore.Scale, 1, NumberField); @@ -43,9 +54,10 @@ export namespace Documents { } let textProto: Document; + const textProtoId = "textProto"; function GetTextPrototype(): Document { if (!textProto) { - textProto = new Document(); + textProto = new Document(textProtoId); textProto.Set(KeyStore.X, new NumberField(0)); textProto.Set(KeyStore.Y, new NumberField(0)); textProto.Set(KeyStore.Width, new NumberField(300)); @@ -64,9 +76,10 @@ export namespace Documents { } let schemaProto: Document; + const schemaProtoId = "schemaProto"; function GetSchemaPrototype(): Document { if (!schemaProto) { - schemaProto = new Document(); + schemaProto = new Document(schemaProtoId); schemaProto.Set(KeyStore.X, new NumberField(0)); schemaProto.Set(KeyStore.Y, new NumberField(0)); schemaProto.Set(KeyStore.Width, new NumberField(300)); @@ -86,6 +99,7 @@ export namespace Documents { let dockProto: Document; + const dockProtoId = "dockProto"; function GetDockPrototype(): Document { if (!dockProto) { dockProto = new Document(); @@ -107,11 +121,11 @@ export namespace Documents { } - let imageProtoId: FIELD_ID; + let imageProto: Document; + const imageProtoId = "imageProto"; function GetImagePrototype(): Document { - if (imageProtoId === undefined) { - let imageProto = new Document(); - imageProtoId = imageProto.Id; + if (!imageProto) { + imageProto = new Document(imageProtoId); imageProto.Set(KeyStore.Title, new TextField("IMAGE PROTO")); imageProto.Set(KeyStore.X, new NumberField(0)); imageProto.Set(KeyStore.Y, new NumberField(0)); @@ -120,26 +134,23 @@ export namespace Documents { imageProto.Set(KeyStore.Layout, new TextField(ImageBox.LayoutString())); // imageProto.SetField(KeyStore.Layout, new TextField('<div style={"background-image: " + {Data}} />')); imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); - // Server.AddDocument(imageProto); return imageProto; } - return new Document(); - // return Server.GetField(imageProtoId) as Document; + return imageProto; } export function ImageDocument(url: string, options: DocumentOptions = {}): Document { let doc = GetImagePrototype().MakeDelegate(); setupOptions(doc, options); doc.Set(KeyStore.Data, new ImageField(new URL(url))); - // Server.AddDocument(doc); - // var sdoc = Server.GetField(doc.Id) as Document; return doc; } let collectionProto: Document; + const collectionProtoId = "collectionProto"; function GetCollectionPrototype(): Document { if (!collectionProto) { - collectionProto = new Document(); + collectionProto = new Document(collectionProtoId); collectionProto.Set(KeyStore.X, new NumberField(0)); collectionProto.Set(KeyStore.Y, new NumberField(0)); collectionProto.Set(KeyStore.Scale, new NumberField(1)); @@ -153,8 +164,8 @@ export namespace Documents { return collectionProto; } - export function CollectionDocument(documents: Array<Document>, options: DocumentOptions = {}): Document { - let doc = GetCollectionPrototype().MakeDelegate(); + export function CollectionDocument(documents: Array<Document>, options: DocumentOptions = {}, id?: string): Document { + let doc = GetCollectionPrototype().MakeDelegate(id); setupOptions(doc, options); doc.Set(KeyStore.Data, new ListField(documents)); return doc; diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index 6bc5fa412..befb9df4c 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -6,7 +6,7 @@ import { NumberField as NumberFieldImport, NumberField } from "../../fields/Numb import { ImageField as ImageFieldImport } from "../../fields/ImageField"; import { TextField as TextFieldImport, TextField } from "../../fields/TextField"; import { RichTextField as RichTextFieldImport } from "../../fields/RichTextField"; -import { KeyStore as KeyStoreImport } from "../../fields/Key"; +import { KeyStore as KeyStoreImport } from "../../fields/KeyStore"; export interface ExecutableScript { (): any; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 197529c91..858c02eb4 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -5,7 +5,7 @@ import * as ReactDOM from 'react-dom'; import { DocumentDecorations } from './DocumentDecorations'; import { Documents } from '../documents/Documents'; import { Document } from '../../fields/Document'; -import { KeyStore, KeyStore as KS } from '../../fields/Key'; +import { KeyStore } from '../../fields/KeyStore'; import { ListField } from '../../fields/ListField'; import { NumberField } from '../../fields/NumberField'; import { TextField } from '../../fields/TextField'; @@ -14,16 +14,21 @@ import { ContextMenu } from './ContextMenu'; import { DocumentView } from './nodes/DocumentView'; import { ImageField } from '../../fields/ImageField'; import { CompileScript } from './../util/Scripting'; +import { Server } from '../Server'; +import { Utils } from '../../Utils'; +import { ServerUtils } from '../../server/ServerUtil'; +import { MessageStore, DocumentTransfer } from '../../server/Message'; +import { Database } from '../../server/database'; configure({ enforceActions: "observed" }); -const mainNodeCollection = new Array<Document>(); -let mainContainer = Documents.DockDocument(mainNodeCollection, { - x: 0, y: 0, title: "main container" -}) +// const mainNodeCollection = new Array<Document>(); +// let mainContainer = Documents.DockDocument(mainNodeCollection, { +// x: 0, y: 0, title: "main container" +// }) window.addEventListener("drop", function (e) { e.preventDefault(); @@ -54,11 +59,78 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { // schemaDocs[4].SetData(KS.Author, "Bob", TextField); // schemaDocs.push(doc2); // const doc7 = Documents.SchemaDocument(schemaDocs) -const docset: Document[] = []; -let doc4 = Documents.CollectionDocument(docset, { - x: 0, y: 400, title: "mini collection" + +const mainDocId = "mainDoc"; +Documents.initProtos(() => { + Utils.EmitCallback(Server.Socket, MessageStore.GetField, mainDocId, (res: any) => { + console.log("HELLO WORLD") + console.log("RESPONSE: " + res) + let mainContainer: Document; + if (res) { + var lid = KeyStore.Layout.Id; + let obj = ServerUtils.FromJson(res) as Document + mainContainer = obj + } + else { + const docset: Document[] = []; + mainContainer = Documents.CollectionDocument(docset, { x: 0, y: 400, title: "mini collection" }, mainDocId); + let args = new DocumentTransfer(mainContainer.ToJson()) + Utils.Emit(Server.Socket, MessageStore.AddDocument, args) + } + + let addImageNode = action(() => { + mainContainer.GetList<Document>(KeyStore.Data, []).push(Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { + x: 0, y: 300, width: 200, height: 200, title: "added note" + })); + }) + let addTextNode = action(() => { + mainContainer.GetList<Document>(KeyStore.Data, []).push(Documents.TextDocument({ + x: 0, y: 300, width: 200, height: 200, title: "added note" + })); + }) + let addColNode = action(() => { + mainContainer.GetList<Document>(KeyStore.Data, []).push(Documents.CollectionDocument([], { + x: 0, y: 300, width: 200, height: 200, title: "added note" + })); + }) + + let clearDatabase = action(() => { + Utils.Emit(Server.Socket, MessageStore.DeleteAll, {}); + }) + + ReactDOM.render(( + <div style={{ position: "absolute", width: "100%", height: "100%" }}> + <DocumentView Document={mainContainer} ContainingCollectionView={undefined} DocumentView={undefined} /> + <DocumentDecorations /> + <ContextMenu /> + <button style={{ + position: 'absolute', + bottom: '0px', + left: '0px', + width: '150px' + }} onClick={addImageNode}>Add Image</button> + <button style={{ + position: 'absolute', + bottom: '25px', + left: '0px', + width: '150px' + }} onClick={addTextNode}>Add Text</button> + <button style={{ + position: 'absolute', + bottom: '50px', + left: '0px', + width: '150px' + }} onClick={addColNode}>Add Collection</button> + <button style={{ + position: 'absolute', + bottom: '75px', + left: '0px', + width: '150px' + }} onClick={clearDatabase}>Clear Database</button> + </div>), + document.getElementById('root')); + }) }); -mainContainer = doc4; // let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { // x: 650, y: 500, width: 600, height: 600, title: "cat 2" // }); @@ -78,45 +150,3 @@ mainContainer = doc4; // mainContainer.Set(KeyStore.Data, mainNodes); //} //); - -let addImageNode = action(() => { - doc4.GetList<Document>(KeyStore.Data, []).push(Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { - x: 0, y: 300, width: 200, height: 200, title: "added note" - })); -}) -let addTextNode = action(() => { - doc4.GetList<Document>(KeyStore.Data, []).push(Documents.TextDocument({ - x: 0, y: 300, width: 200, height: 200, title: "added note" - })); -}) -let addColNode = action(() => { - doc4.GetList<Document>(KeyStore.Data, []).push(Documents.CollectionDocument([], { - x: 0, y: 300, width: 200, height: 200, title: "added note" - })); -}) - -ReactDOM.render(( - <div style={{ position: "absolute", width: "100%", height: "100%" }}> - <DocumentView Document={mainContainer} ContainingCollectionView={undefined} DocumentView={undefined} /> - <DocumentDecorations /> - <ContextMenu /> - <button style={{ - position: 'absolute', - bottom: '0px', - left: '0px', - width: '150px' - }} onClick={addImageNode}>Add Image</button> - <button style={{ - position: 'absolute', - bottom: '25px', - left: '0px', - width: '150px' - }} onClick={addTextNode}>Add Text</button> - <button style={{ - position: 'absolute', - bottom: '50px', - left: '0px', - width: '150px' - }} onClick={addColNode}>Add Collection</button> - </div>), - document.getElementById('root'));
\ No newline at end of file diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 9aee9c10f..d9e261f55 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,8 +1,8 @@ import { observer } from "mobx-react"; -import { KeyStore } from "../../../fields/Key"; +import { KeyStore } from "../../../fields/KeyStore"; import React = require("react"); import FlexLayout from "flexlayout-react"; -import { action, observable, computed } from "mobx"; +import { action, computed } from "mobx"; import { Document } from "../../../fields/Document"; import { DocumentView } from "../nodes/DocumentView"; import { ListField } from "../../../fields/ListField"; @@ -13,17 +13,18 @@ import 'golden-layout/src/css/goldenlayout-dark-theme.css'; import * as GoldenLayout from "golden-layout"; import * as ReactDOM from 'react-dom'; import { DragManager } from "../../util/DragManager"; -import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; +import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; +import { FieldView } from "../nodes/FieldView"; @observer export class CollectionDockingView extends CollectionViewBase { private static UseGoldenLayout = true; - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionDockingView"); } + public static LayoutString() { return FieldView.LayoutString(CollectionDockingView) } private _containerRef = React.createRef<HTMLDivElement>(); @computed private get modelForFlexLayout() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; + const { fieldKey: fieldKey, doc: Document } = this.props; const value: Document[] = Document.GetData(fieldKey, ListField, []); var docs = value.map(doc => { return { type: 'tabset', weight: 50, selected: 0, children: [{ type: "tab", name: doc.Title, component: doc.Id }] }; @@ -39,7 +40,7 @@ export class CollectionDockingView extends CollectionViewBase { } @computed private get modelForGoldenLayout(): any { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; + const { fieldKey: fieldKey, doc: Document } = this.props; const value: Document[] = Document.GetData(fieldKey, ListField, []); var docs = value.map(doc => { return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } }; @@ -50,9 +51,6 @@ export class CollectionDockingView extends CollectionViewBase { }, content: [{ type: 'row', content: docs }] }); } - constructor(props: CollectionViewProps) { - super(props); - } componentDidMount: () => void = () => { if (this._containerRef.current && CollectionDockingView.UseGoldenLayout) { @@ -67,8 +65,8 @@ export class CollectionDockingView extends CollectionViewBase { @action - onResize = (event: any) => { - var cur = this.props.ContainingDocumentView!.MainContent.current; + onResize = () => { + var cur = this.props.DocumentViewForField!.MainContent.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 CollectionDockingView.myLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height); @@ -91,7 +89,7 @@ export class CollectionDockingView extends CollectionViewBase { if (component === "button") { return <button>{node.getName()}</button>; } - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; + const { fieldKey: fieldKey, doc: Document } = this.props; const value: Document[] = Document.GetData(fieldKey, ListField, []); for (var i: number = 0; i < value.length; i++) { if (value[i].Id === component) { @@ -195,7 +193,6 @@ export class CollectionDockingView extends CollectionViewBase { goldenLayoutFactory() { CollectionDockingView.myLayout = this.modelForGoldenLayout; - var layout = CollectionDockingView.myLayout; CollectionDockingView.myLayout.on('tabCreated', function (tab: any) { if (CollectionDockingView._dragDiv) { CollectionDockingView._dragDiv.removeChild(CollectionDockingView._dragElement); @@ -251,10 +248,9 @@ export class CollectionDockingView extends CollectionViewBase { render() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetData(fieldKey, ListField, []); + const { fieldKey: fieldKey, doc: Document } = this.props; // bcz: not sure why, but I need these to force the flexlayout to update when the collection size changes. - var s = this.props.ContainingDocumentView != undefined ? this.props.ContainingDocumentView!.ScalingToScreenSpace : 1; + var s = this.props.DocumentViewForField != undefined ? this.props.DocumentViewForField!.ScalingToScreenSpace : 1; var w = Document.GetData(KeyStore.Width, NumberField, Number(0)) / s; var h = Document.GetData(KeyStore.Height, NumberField, Number(0)) / s; diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 9cf29d000..e6b1d103d 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -5,28 +5,25 @@ import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocum import { DragManager } from "../../util/DragManager"; import "./CollectionFreeFormView.scss"; import { Utils } from "../../../Utils"; -import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; +import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; import { SelectionManager } from "../../util/SelectionManager"; -import { Key, KeyStore } from "../../../fields/Key"; +import { KeyStore } from "../../../fields/KeyStore"; import { Document } from "../../../fields/Document"; import { ListField } from "../../../fields/ListField"; import { NumberField } from "../../../fields/NumberField"; import { Documents } from "../../documents/Documents"; import { FieldWaiting } from "../../../fields/Field"; +import { FakeJsxArgs } from "../nodes/DocumentView"; +import { FieldView } from "../nodes/FieldView"; @observer export class CollectionFreeFormView extends CollectionViewBase { - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionFreeFormView"); } - private _containerRef = React.createRef<HTMLDivElement>(); + public static LayoutString() { return FieldView.LayoutString(CollectionFreeFormView); } private _canvasRef = React.createRef<HTMLDivElement>(); private _nodeContainerRef = React.createRef<HTMLDivElement>(); private _lastX: number = 0; private _lastY: number = 0; - constructor(props: CollectionViewProps) { - super(props); - } - @action drop = (e: Event, de: DragManager.DropEvent) => { const doc = de.data["document"]; @@ -39,7 +36,7 @@ export class CollectionFreeFormView extends CollectionViewBase { const xOffset = de.data["xOffset"] as number || 0; const yOffset = de.data["yOffset"] as number || 0; const { scale, translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!); - let sscale = this.props.ContainingDocumentView!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)) + let sscale = this.props.DocumentViewForField!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)) const screenX = de.x - xOffset; const screenY = de.y - yOffset; const docX = (screenX - translateX) / sscale / scale; @@ -51,9 +48,13 @@ export class CollectionFreeFormView extends CollectionViewBase { e.stopPropagation(); } - componentDidMount() { - if (this._containerRef.current) { - DragManager.MakeDropTarget(this._containerRef.current, { + private dropDisposer?: DragManager.DragDropDisposer; + createDropTarget = (ele: HTMLDivElement) => { + if (this.dropDisposer) { + this.dropDisposer(); + } + if (ele) { + this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop } @@ -88,11 +89,11 @@ export class CollectionFreeFormView extends CollectionViewBase { if (!e.cancelBubble && this.active) { e.preventDefault(); e.stopPropagation(); - let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace; - let x = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); - let y = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); - this.props.DocumentForCollection.SetData(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); - this.props.DocumentForCollection.SetData(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); + let currScale: number = this.props.DocumentViewForField!.ScalingToScreenSpace; + let x = this.props.doc.GetData(KeyStore.PanX, NumberField, Number(0)); + let y = this.props.doc.GetData(KeyStore.PanY, NumberField, Number(0)); + this.props.doc.SetData(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); + this.props.doc.SetData(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); } this._lastX = e.pageX; this._lastY = e.pageY; @@ -102,7 +103,7 @@ export class CollectionFreeFormView extends CollectionViewBase { onPointerWheel = (e: React.WheelEvent): void => { e.stopPropagation(); - let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); + let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.DocumentViewForField!.TransformToLocalPoint(e.pageX, e.pageY); var deltaScale = (1 - (e.deltaY / 1000)) * Ss; @@ -112,9 +113,9 @@ export class CollectionFreeFormView extends CollectionViewBase { let dx = ContainerX - newContainerX; let dy = ContainerY - newContainerY; - this.props.DocumentForCollection.Set(KeyStore.Scale, new NumberField(deltaScale)); - this.props.DocumentForCollection.SetData(KeyStore.PanX, Panxx + dx, NumberField); - this.props.DocumentForCollection.SetData(KeyStore.PanY, Panyy + dy, NumberField); + this.props.doc.Set(KeyStore.Scale, new NumberField(deltaScale)); + this.props.doc.SetData(KeyStore.PanX, Panxx + dx, NumberField); + this.props.doc.SetData(KeyStore.PanY, Panyy + dy, NumberField); } @action @@ -124,8 +125,8 @@ export class CollectionFreeFormView extends CollectionViewBase { let fReader = new FileReader() let file = e.dataTransfer.items[0].getAsFile(); let that = this; - const panx: number = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); - const pany: number = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); + const panx: number = this.props.doc.GetData(KeyStore.PanX, NumberField, Number(0)); + const pany: number = this.props.doc.GetData(KeyStore.PanY, NumberField, Number(0)); let x = e.pageX - panx let y = e.pageY - pany @@ -135,11 +136,11 @@ export class CollectionFreeFormView extends CollectionViewBase { let doc = Documents.ImageDocument(url, { x: x, y: y }) - let docs = that.props.DocumentForCollection.GetT(KeyStore.Data, ListField); + let docs = that.props.doc.GetT(KeyStore.Data, ListField); if (docs != FieldWaiting) { if (!docs) { docs = new ListField<Document>(); - that.props.DocumentForCollection.Set(KeyStore.Data, docs) + that.props.doc.Set(KeyStore.Data, docs) } docs.Data.push(doc); } @@ -156,7 +157,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action bringToFront(doc: CollectionFreeFormDocumentView) { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; + const { fieldKey: fieldKey, doc: Document } = this.props; const value: Document[] = Document.GetList<Document>(fieldKey, []); var topmost = value.reduce((topmost, d) => Math.max(d.GetNumber(KeyStore.ZIndex, 0), topmost), -1000); @@ -173,8 +174,12 @@ export class CollectionFreeFormView extends CollectionViewBase { } render() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetList<Document>(fieldKey, []); + const { fieldKey: fieldKey, doc: Document } = this.props; + // const value: Document[] = Document.GetList<Document>(fieldKey, []); + const lvalue = Document.GetT<ListField<Document>>(fieldKey, ListField); + if (!lvalue || lvalue === "<Waiting>") { + return <p>Error loading collection data</p> + } const panx: number = Document.GetNumber(KeyStore.PanX, 0); const pany: number = Document.GetNumber(KeyStore.PanY, 0); const currScale: number = Document.GetNumber(KeyStore.Scale, 1); @@ -189,11 +194,11 @@ export class CollectionFreeFormView extends CollectionViewBase { onContextMenu={(e) => e.preventDefault()} onDrop={this.onDrop} onDragOver={this.onDragOver} - ref={this._containerRef}> + ref={this.createDropTarget}> <div className="collectionfreeformview" style={{ transform: `translate(${panx}px, ${pany}px) scale(${currScale}, ${currScale})`, transformOrigin: `left, top` }} ref={this._canvasRef}> <div className="node-container" ref={this._nodeContainerRef}> - {value.map(doc => { + {lvalue.Data.map(doc => { return (<CollectionFreeFormDocumentView key={doc.Id} ContainingCollectionView={this} Document={doc} DocumentView={undefined} />); })} </div> diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 2d5bd6c99..9f32ccb72 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -11,13 +11,13 @@ import { CollectionViewBase } from "./CollectionViewBase"; import { DocumentView } from "../nodes/DocumentView"; import { EditableView } from "../EditableView"; import { CompileScript, ToField } from "../../util/Scripting"; -import { KeyStore as KS, Key } from "../../../fields/Key"; +import { KeyStore as KS } from "../../../fields/KeyStore"; import { Document } from "../../../fields/Document"; import { Field } from "../../../fields/Field"; @observer export class CollectionSchemaView extends CollectionViewBase { - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionSchemaView"); } + public static LayoutString() { return FieldView.LayoutString(CollectionSchemaView); } @observable selectedIndex = 0; @@ -97,7 +97,7 @@ export class CollectionSchemaView extends CollectionViewBase { } render() { - const { DocumentForCollection: Document, CollectionFieldKey: fieldKey } = this.props; + const { doc: Document, fieldKey: fieldKey } = this.props; const children = Document.GetList<Document>(fieldKey, []); const columns = Document.GetList(KS.ColumnsKey, [KS.Title, KS.Data, KS.Author]) diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 09e8ec729..4fcbb1699 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -2,7 +2,7 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { Opt } from "../../../fields/Field"; -import { Key, KeyStore } from "../../../fields/Key"; +import { Key } from "../../../fields/Key"; import { ListField } from "../../../fields/ListField"; import { SelectionManager } from "../../util/SelectionManager"; import { ContextMenu } from "../ContextMenu"; @@ -10,42 +10,33 @@ import React = require("react"); import { DocumentView } from "../nodes/DocumentView"; import { CollectionDockingView } from "./CollectionDockingView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; - - -export interface CollectionViewProps { - CollectionFieldKey: Key; - DocumentForCollection: Document; - ContainingDocumentView: Opt<DocumentView>; -} +import { FieldViewProps } from "../nodes/FieldView"; export const COLLECTION_BORDER_WIDTH = 2; @observer -export class CollectionViewBase extends React.Component<CollectionViewProps> { +export class CollectionViewBase extends React.Component<FieldViewProps> { - public static LayoutString(collectionType: string) { - return `<${collectionType} DocumentForCollection={Document} CollectionFieldKey={DataKey} ContainingDocumentView={DocumentView}/>`; - } @computed public get active(): boolean { - var isSelected = (this.props.ContainingDocumentView instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.ContainingDocumentView)); + var isSelected = (this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)); var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); - var topMost = this.props.ContainingDocumentView != undefined && ( - this.props.ContainingDocumentView.props.ContainingCollectionView == undefined || - this.props.ContainingDocumentView.props.ContainingCollectionView instanceof CollectionDockingView); + var topMost = this.props.DocumentViewForField != undefined && ( + this.props.DocumentViewForField.props.ContainingCollectionView == undefined || + this.props.DocumentViewForField.props.ContainingCollectionView instanceof CollectionDockingView); return isSelected || childSelected || topMost; } @action addDocument = (doc: Document): void => { //TODO This won't create the field if it doesn't already exist - const value = this.props.DocumentForCollection.GetData(this.props.CollectionFieldKey, ListField, new Array<Document>()) + const value = this.props.doc.GetData(this.props.fieldKey, ListField, new Array<Document>()) value.push(doc); } @action removeDocument = (doc: Document): void => { //TODO This won't create the field if it doesn't already exist - const value = this.props.DocumentForCollection.GetData(this.props.CollectionFieldKey, ListField, new Array<Document>()) + const value = this.props.doc.GetData(this.props.fieldKey, ListField, new Array<Document>()) if (value.indexOf(doc) !== -1) { value.splice(value.indexOf(doc), 1) diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 1d53cedc4..bfd50da81 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,6 +1,6 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; -import { Key, KeyStore } from "../../../fields/Key"; +import { KeyStore } from "../../../fields/KeyStore"; import { NumberField } from "../../../fields/NumberField"; import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; @@ -10,6 +10,7 @@ import { ContextMenu } from "../ContextMenu"; import "./NodeView.scss"; import React = require("react"); import { DocumentView, DocumentViewProps } from "./DocumentView"; +import { Utils } from "../../../Utils"; @observer @@ -188,7 +189,6 @@ export class CollectionFreeFormDocumentView extends DocumentView { if (this.topMost) { ContextMenu.Instance.clearItems() ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) } else { // DocumentViews should stop propogation of this event @@ -198,20 +198,25 @@ export class CollectionFreeFormDocumentView extends DocumentView { ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) ContextMenu.Instance.addItem({ description: "Open Right", event: this.openRight }) ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) SelectionManager.SelectDoc(this, e.ctrlKey); } + + ContextMenu.Instance.addItem({ + description: "Copy ID", event: () => { + Utils.CopyText(this.props.Document.Id) + } + }) + ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) } render() { - var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView; return ( <div className="node" ref={this._mainCont} style={{ - transform: freestyling ? this.transform : "", - width: freestyling ? this.width : "100%", - height: freestyling ? this.height : "100%", - position: freestyling ? "absolute" : "relative", - zIndex: freestyling ? this.zIndex : 0, + transform: this.transform, + width: this.width, + height: this.height, + position: "absolute", + zIndex: this.zIndex, }} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}> diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 730ce62f2..3767d28c6 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,8 +1,9 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; -import { Opt, FieldWaiting } from "../../../fields/Field"; -import { Key, KeyStore } from "../../../fields/Key"; +import { Opt, FieldWaiting, Field } from "../../../fields/Field"; +import { Key } from "../../../fields/Key"; +import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; import { NumberField } from "../../../fields/NumberField"; import { TextField } from "../../../fields/TextField"; @@ -22,6 +23,48 @@ export interface DocumentViewProps { DocumentView: Opt<DocumentView> // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way? ContainingCollectionView: Opt<CollectionViewBase>; } +export interface JsxArgs extends DocumentViewProps { + Keys: { [name: string]: Key } + Fields: { [name: string]: Field } +} + +/* +This function is pretty much a hack that lets us fill out the fields in JsxArgs with something that +jsx-to-string can recover the jsx from +Example usage of this function: + public static LayoutString() { + let args = FakeJsxArgs(["Data"]); + return jsxToString( + <CollectionFreeFormView + doc={args.Document} + fieldKey={args.Keys.Data} + DocumentViewForField={args.DocumentView} />, + { useFunctionCode: true, functionNameOnly: true } + ) + } +*/ +export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { + let Keys: { [name: string]: any } = {} + let Fields: { [name: string]: any } = {} + for (const key of keys) { + let fn = () => { } + Object.defineProperty(fn, "name", { value: key + "Key" }) + Keys[key] = fn; + } + for (const field of fields) { + let fn = () => { } + Object.defineProperty(fn, "name", { value: field }) + Fields[field] = fn; + } + let args: JsxArgs = { + Document: function Document() { }, + DocumentView: function DocumentView() { }, + Keys, + Fields + } as any; + return args; +} + @observer export class DocumentView extends React.Component<DocumentViewProps> { @@ -50,9 +93,9 @@ export class DocumentView extends React.Component<DocumentViewProps> { @computed public get ScalingToScreenSpace(): number { if (this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) { - let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetData(KeyStore.Scale, NumberField, Number(1)); - return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss; + this.props.ContainingCollectionView.props.DocumentViewForField != undefined) { + let ss = this.props.ContainingCollectionView.props.doc.GetData(KeyStore.Scale, NumberField, Number(1)); + return this.props.ContainingCollectionView.props.DocumentViewForField.ScalingToScreenSpace * ss; } return 1; } @@ -64,8 +107,8 @@ export class DocumentView extends React.Component<DocumentViewProps> { // if this collection view is nested within another collection view, then // first transform the screen point into the parent collection's coordinate space. let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ? - this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) : + this.props.ContainingCollectionView.props.DocumentViewForField != undefined ? + this.props.ContainingCollectionView.props.DocumentViewForField.TransformToLocalPoint(screenX, screenY) : { LocalX: screenX, LocalY: screenY }; let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH; let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH; @@ -113,7 +156,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { // if this collection view is nested within another collection view, then // first transform the local point into the parent collection's coordinate space. - let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; + let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.DocumentViewForField : undefined; if (containingDocView != undefined) { let ss = containingDocView.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)); let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; @@ -128,6 +171,10 @@ export class DocumentView extends React.Component<DocumentViewProps> { render() { let bindings = { ...this.props } as any; + let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); + if (!lkeys || lkeys === "<Waiting>") { + return <p>Error loading layout keys</p>; + } for (const key of this.layoutKeys) { bindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 12371eb2e..fae124528 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -25,7 +25,7 @@ export interface FieldViewProps { @observer export class FieldView extends React.Component<FieldViewProps> { - public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; } + public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; } @computed get field(): FieldValue<Field> { const { doc, fieldKey } = this.props; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 8bc4c902c..39d7bf4f0 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -34,7 +34,7 @@ import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView @observer export class FormattedTextBox extends React.Component<FieldViewProps> { - public static LayoutString() { return FieldView.LayoutString("FormattedTextBox"); } + public static LayoutString() { return FieldView.LayoutString(FormattedTextBox) } private _ref: React.RefObject<HTMLDivElement>; private _editorView: Opt<EditorView>; private _reactionDisposer: Opt<IReactionDisposer>; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index ab20f140c..013b8b7d3 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -14,7 +14,7 @@ import { observable, action } from 'mobx'; @observer export class ImageBox extends React.Component<FieldViewProps> { - public static LayoutString() { return FieldView.LayoutString("ImageBox"); } + public static LayoutString() { return FieldView.LayoutString(ImageBox) } private _ref: React.RefObject<HTMLDivElement>; private _downX: number = 0; private _downY: number = 0; |
