diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 79 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 21 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 47 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 12 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.scss | 31 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.tsx | 85 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValuePair.tsx | 58 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.scss | 14 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 38 | ||||
| -rw-r--r-- | src/client/views/nodes/WebView.tsx | 22 |
10 files changed, 322 insertions, 85 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 50dc9ddc1..e01e1d4cd 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -12,26 +12,29 @@ import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; -import { WebView } from "./WebView"; import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; +import { Documents } from "../../documents/Documents" +import { KeyValueBox } from "./KeyValueBox" +import { WebBox } from "../nodes/WebBox"; 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 ContentScaling: () => number; PanelWidth: () => number; PanelHeight: () => number; + focus: (doc: Document) => void; + SelectOnLoad: boolean; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key } @@ -77,29 +80,23 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { @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>()); } - 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; if (e.shiftKey && e.buttons === 1) { - CollectionDockingView.Instance.StartOtherDrag(this._mainCont.current!, this.props.Document); + CollectionDockingView.Instance.StartOtherDrag(this.props.Document, e); e.stopPropagation(); } else { - this._contextMenuCanOpen = true; if (this.active && !e.isDefaultPrevented()) { e.stopPropagation(); if (e.buttons === 2) { @@ -112,16 +109,14 @@ export class DocumentView extends React.Component<DocumentViewProps> { } } } - onPointerMove = (e: PointerEvent): void => { if (e.cancelBubble) { - this._contextMenuCanOpen = false; return; } if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { - this._contextMenuCanOpen = false; + document.removeEventListener("pointermove", this.onPointerMove) + document.removeEventListener("pointerup", this.onPointerUp) 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 } = {}; dragData["documentView"] = this; @@ -129,7 +124,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { dragData["yOffset"] = e.y - top; DragManager.StartDrag(this._mainCont.current, dragData, { handlers: { - dragComplete: action((e: DragManager.DragCompleteEvent) => { }), + dragComplete: action(() => { }), }, hideSource: true }) @@ -138,7 +133,6 @@ export class DocumentView extends React.Component<DocumentViewProps> { e.stopPropagation(); e.preventDefault(); } - onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove) document.removeEventListener("pointerup", this.onPointerUp) @@ -148,17 +142,24 @@ export class DocumentView extends React.Component<DocumentViewProps> { } } - deleteClicked = (e: React.MouseEvent): void => { + deleteClicked = (): void => { if (this.props.RemoveDocument) { this.props.RemoveDocument(this.props.Document); } } + + fieldsClicked = (e: React.MouseEvent): void => { + if (this.props.AddDocument) { + this.props.AddDocument(Documents.KVPDocument(this.props.Document)); + } + } 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.displayMenu(e.pageX - 15, e.pageY - 15) } + closeFullScreenClicked = (e: React.MouseEvent): void => { CollectionDockingView.Instance.CloseFullScreen(); ContextMenu.Instance.clearItems(); @@ -168,18 +169,18 @@ export class DocumentView extends React.Component<DocumentViewProps> { @action onContextMenu = (e: React.MouseEvent): void => { - e.preventDefault() e.stopPropagation(); - if (!SelectionManager.IsSelected(this) || !this._contextMenuCanOpen) { + let moved = Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3; + if (moved || e.isDefaultPrevented()) { + e.preventDefault() return; } + e.preventDefault() - ContextMenu.Instance.clearItems() ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) + ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked }) + ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) }) ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) }) - 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.displayMenu(e.pageX - 15, e.pageY - 15) if (!this.topMost) { @@ -191,11 +192,9 @@ export class DocumentView extends React.Component<DocumentViewProps> { 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 }} + components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox }} bindings={this._documentBindings} jsx={this.layout} showWarnings={true} @@ -203,27 +202,34 @@ export class DocumentView extends React.Component<DocumentViewProps> { /> } + isSelected = () => { + return SelectionManager.IsSelected(this); + } + + select = (ctrlPressed: boolean) => { + SelectionManager.SelectDoc(this, ctrlPressed) + } + 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: this.isSelected, + select: this.select, + focus: this.props.focus }; 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); @@ -233,13 +239,12 @@ export class DocumentView extends React.Component<DocumentViewProps> { width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%", height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%", transformOrigin: "left top", - transform: `scale(${scaling},${scaling})` + transform: `scale(${scaling} , ${scaling})` }} onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown} - > + onPointerDown={this.onPointerDown} > {this.mainContent} </div> ) } -} +}
\ No newline at end of file diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index b71309bf5..9e63006d1 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,17 +1,17 @@ import React = require("react") import { observer } from "mobx-react"; import { computed } from "mobx"; -import { Field, Opt, FieldWaiting, FieldValue } from "../../../fields/Field"; +import { Field, FieldWaiting, FieldValue } from "../../../fields/Field"; import { Document } from "../../../fields/Document"; import { TextField } from "../../../fields/TextField"; import { NumberField } from "../../../fields/NumberField"; import { RichTextField } from "../../../fields/RichTextField"; import { ImageField } from "../../../fields/ImageField"; +import { WebField } from "../../../fields/WebField"; import { Key } from "../../../fields/Key"; import { FormattedTextBox } from "./FormattedTextBox"; import { ImageBox } from "./ImageBox"; -import { HtmlField } from "../../../fields/HtmlField"; -import { WebView } from "./WebView"; +import { WebBox } from "./WebBox"; // // these properties get assigned through the render() method of the DocumentView when it creates this node. @@ -24,12 +24,15 @@ export interface FieldViewProps { isSelected: () => boolean; select: () => void; isTopMost: boolean; + selectOnLoad: boolean; bindings: any; } @observer export class FieldView extends React.Component<FieldViewProps> { - public static LayoutString(fieldType: { name: string }, fieldStr: string = "DataKey") { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={${fieldStr}} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } + public static LayoutString(fieldType: { name: string }, fieldStr: string = "DataKey") { + return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={${fieldStr}} isSelected={isSelected} select={select} selectOnLoad={SelectOnLoad} isTopMost={isTopMost} />`; + } @computed get field(): FieldValue<Field> { @@ -50,12 +53,16 @@ export class FieldView extends React.Component<FieldViewProps> { else if (field instanceof ImageField) { return <ImageBox {...this.props} /> } + else if (field instanceof WebField) { + return <WebBox {...this.props} /> + } + // bcz: this belongs here, but it doesn't render well so taking it out for now + // else if (field instanceof HtmlField) { + // return <WebBox {...this.props} /> + // } else if (field instanceof NumberField) { return <p>{field.Data}</p> } - else if (field instanceof HtmlField) { - return <WebView {...this.props} /> - } else if (field != FieldWaiting) { return <p>{JSON.stringify(field.GetValue())}</p> } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index a0f662f18..a6cee9957 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -5,15 +5,15 @@ import { keymap } from "prosemirror-keymap"; import { schema } from "../../util/RichTextSchema"; import { EditorState, Transaction, } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; -import { Opt, FieldWaiting, FieldValue } from "../../../fields/Field"; +import { Opt, FieldWaiting } from "../../../fields/Field"; import "./FormattedTextBox.scss"; -import { KeyStore } from "../../../fields/KeyStore"; import React = require("react") import { RichTextField } from "../../../fields/RichTextField"; import { FieldViewProps, FieldView } from "./FieldView"; import { Plugin } from 'prosemirror-state' import { Decoration, DecorationSet } from 'prosemirror-view' import { TooltipTextMenu } from "../../util/TooltipTextMenu" +import { ContextMenu } from "../../views/ContextMenu"; @@ -45,7 +45,6 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { super(props); this._ref = React.createRef(); - this.onChange = this.onChange.bind(this); } @@ -53,16 +52,12 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { if (this._editorView) { const state = this._editorView.state.apply(tx); this._editorView.updateState(state); - const { doc, fieldKey } = this.props; - doc.SetData(fieldKey, JSON.stringify(state.toJSON()), RichTextField); + this.props.doc.SetData(this.props.fieldKey, JSON.stringify(state.toJSON()), RichTextField); } } componentDidMount() { let state: EditorState; - const { doc, fieldKey } = this.props; - - // let mySchema = new Schema({ nodes, marks }) const config = { schema, plugins: [ @@ -71,11 +66,10 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { keymap(baseKeymap), this.tooltipMenuPlugin() ] - }; - let field = doc.GetT(fieldKey, RichTextField); - if (field && field != FieldWaiting) { // bcz: don't think this works + let field = this.props.doc.GetT(this.props.fieldKey, RichTextField); + if (field && field != FieldWaiting) { state = EditorState.fromJSON(config, JSON.parse(field.Data)); } else { state = EditorState.create(config); @@ -95,9 +89,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field))); } }) - - //if tagged to be selected when created, then select & focus - if (this.props.doc.GetNumber(KeyStore.SelectOnLoaded, 0)) { + if (this.props.selectOnLoad) { this.props.select(); this._editorView!.focus(); } @@ -118,15 +110,35 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { @action onChange(e: React.ChangeEvent<HTMLInputElement>) { - const { fieldKey, doc } = this.props; - doc.SetData(fieldKey, e.target.value, RichTextField); + this.props.doc.SetData(this.props.fieldKey, e.target.value, RichTextField); } onPointerDown = (e: React.PointerEvent): void => { - let me = this; if (e.buttons === 1 && this.props.isSelected()) { e.stopPropagation(); } } + + //REPLACE THIS WITH CAPABILITIES SPECIFIC TO THIS TYPE OF NODE + textCapability = (e: React.MouseEvent): void => { + } + + 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 => { e.stopPropagation(); } @@ -142,6 +154,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { render() { return (<div className="formattedTextBox-cont" onPointerDown={this.onPointerDown} + onContextMenu={this.specificContextMenu} onWheel={this.onPointerWheel} ref={this._ref} />) } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4fe73fb8d..8c44395f4 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -7,9 +7,9 @@ import { ImageField } from '../../../fields/ImageField'; import { FieldViewProps, FieldView } from './FieldView'; import { FieldWaiting } from '../../../fields/Field'; import { observer } from "mobx-react" +import { ContextMenu } from "../../views/ContextMenu"; import { observable, action } from 'mobx'; import { KeyStore } from '../../../fields/KeyStore'; -import { element } from 'prop-types'; @observer export class ImageBox extends React.Component<FieldViewProps> { @@ -89,13 +89,21 @@ export class ImageBox extends React.Component<FieldViewProps> { } } + //REPLACE THIS WITH CAPABILITIES SPECIFIC TO THIS TYPE OF NODE + imageCapability = (e: React.MouseEvent): void => { + } + + specificContextMenu = (e: React.MouseEvent): void => { + ContextMenu.Instance.addItem({ description: "Image Capability", event: this.imageCapability }); + } + render() { let field = this.props.doc.Get(this.props.fieldKey); let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif"; let nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 1); return ( - <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} > + <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} onContextMenu={this.specificContextMenu}> <img src={path} width={nativeWidth} alt="Image not found" ref={this._imgRef} onLoad={this.onLoad} /> {this.lightbox(path)} </div>) diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss new file mode 100644 index 000000000..1295266e5 --- /dev/null +++ b/src/client/views/nodes/KeyValueBox.scss @@ -0,0 +1,31 @@ +.keyValueBox-cont { + overflow-y:scroll; + height: 100%; + border: black; + border-width: 1px; + border-style: solid; + box-sizing: border-box; + display: inline-block; + .imageBox-cont img { + max-height:45px; + height: auto; + } +} +.keyValueBox-table { + position: relative; +} +.keyValueBox-header { + background:gray; +} +.keyValueBox-evenRow { + background: white; + .formattedTextBox-cont { + background: white; + } +} +.keyValueBox-oddRow { + background: lightGray; + .formattedTextBox-cont { + background: lightgray; + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx new file mode 100644 index 000000000..e8ebd50be --- /dev/null +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -0,0 +1,85 @@ + +import { IReactionDisposer } from 'mobx'; +import { observer } from "mobx-react"; +import { EditorView } from 'prosemirror-view'; +import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app +import { Document } from '../../../fields/Document'; +import { Opt, FieldWaiting } from '../../../fields/Field'; +import { KeyStore } from '../../../fields/KeyStore'; +import { FieldView, FieldViewProps } from './FieldView'; +import { KeyValuePair } from "./KeyValuePair"; +import "./KeyValueBox.scss"; +import React = require("react") + +@observer +export class KeyValueBox extends React.Component<FieldViewProps> { + + public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(KeyValueBox, fieldStr) } + private _ref: React.RefObject<HTMLDivElement>; + private _editorView: Opt<EditorView>; + private _reactionDisposer: Opt<IReactionDisposer>; + + + constructor(props: FieldViewProps) { + super(props); + + this._ref = React.createRef(); + } + + + + shouldComponentUpdate() { + return false; + } + + + onPointerDown = (e: React.PointerEvent): void => { + if (e.buttons === 1 && this.props.isSelected()) { + e.stopPropagation(); + } + } + onPointerWheel = (e: React.WheelEvent): void => { + e.stopPropagation(); + } + + createTable = () => { + let doc = this.props.doc.GetT(KeyStore.Data, Document); + if (!doc || doc == FieldWaiting) { + return <tr><td>Loading...</td></tr> + } + let realDoc = doc; + + let ids: { [key: string]: string } = {}; + let protos = doc.GetAllPrototypes(); + for (const proto of protos) { + proto._proxies.forEach((val, key) => { + if (!(key in ids)) { + ids[key] = key; + } + }) + } + + let rows: JSX.Element[] = []; + let i = 0; + for (let key in ids) { + rows.push(<KeyValuePair doc={realDoc} rowStyle={"keyValueBox-" + (i++ % 2 ? "oddRow" : "evenRow")} fieldId={key} key={key} />) + } + return rows; + } + + + render() { + + return (<div className="keyValueBox-cont" onWheel={this.onPointerWheel}> + <table className="keyValueBox-table"> + <tbody> + <tr className="keyValueBox-header"> + <th>Key</th> + <th>Fields</th> + </tr> + {this.createTable()} + </tbody> + </table> + </div>) + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx new file mode 100644 index 000000000..a97e98313 --- /dev/null +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -0,0 +1,58 @@ +import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app +import "./KeyValueBox.scss"; +import React = require("react") +import { FieldViewProps, FieldView } from './FieldView'; +import { Opt, Field } from '../../../fields/Field'; +import { observer } from "mobx-react" +import { observable, action } from 'mobx'; +import { Document } from '../../../fields/Document'; +import { Key } from '../../../fields/Key'; +import { Server } from "../../Server" + +// Represents one row in a key value plane + +export interface KeyValuePairProps { + rowStyle: string; + fieldId: string; + doc: Document; +} +@observer +export class KeyValuePair extends React.Component<KeyValuePairProps> { + + @observable + private key: Opt<Key> + + constructor(props: KeyValuePairProps) { + super(props); + Server.GetField(this.props.fieldId, + action((field: Opt<Field>) => { + if (field) { + this.key = field as Key; + } + })); + + } + + + render() { + if (!this.key) { + return <tr><td>error</td><td></td></tr> + + } + let props: FieldViewProps = { + doc: this.props.doc, + fieldKey: this.key, + isSelected: () => false, + select: () => { }, + isTopMost: false, + bindings: {}, + selectOnLoad: false, + } + return ( + <tr className={this.props.rowStyle}> + <td>{this.key.Name}</td> + <td><FieldView {...props} /></td> + </tr> + ) + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss new file mode 100644 index 000000000..e72b3c4da --- /dev/null +++ b/src/client/views/nodes/WebBox.scss @@ -0,0 +1,14 @@ + +.webBox-cont { + padding: 0vw; + position: absolute; + width: 100%; + height: 100%; +} + +.webBox-button { + padding : 0vw; + border: none; + width : 100%; + height: 100%; +}
\ No newline at end of file diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx new file mode 100644 index 000000000..2ca8d49ce --- /dev/null +++ b/src/client/views/nodes/WebBox.tsx @@ -0,0 +1,38 @@ +import "./WebBox.scss"; +import React = require("react") +import { WebField } from '../../../fields/WebField'; +import { FieldViewProps, FieldView } from './FieldView'; +import { FieldWaiting } from '../../../fields/Field'; +import { observer } from "mobx-react" +import { computed } from 'mobx'; +import { KeyStore } from '../../../fields/KeyStore'; + +@observer +export class WebBox extends React.Component<FieldViewProps> { + + public static LayoutString() { return FieldView.LayoutString(WebBox); } + + constructor(props: FieldViewProps) { + super(props); + } + + @computed get html(): string { return this.props.doc.GetHtml(KeyStore.Data, ""); } + + render() { + let field = this.props.doc.Get(this.props.fieldKey); + let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : + field instanceof WebField ? field.Data.href : "https://crossorigin.me/" + "https://cs.brown.edu"; + + let content = this.html ? + <span dangerouslySetInnerHTML={{ __html: this.html }}></span> : + <div style={{ width: "100%", height: "100%", position: "absolute" }}> + <iframe src={path} style={{ position: "absolute", width: "100%", height: "100%" }}></iframe> + {this.props.isSelected() ? (null) : <div style={{ width: "100%", height: "100%", position: "absolute" }} />} + </div>; + + return ( + <div className="webBox-cont" > + {content} + </div>) + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/WebView.tsx b/src/client/views/nodes/WebView.tsx deleted file mode 100644 index 717aa8bf5..000000000 --- a/src/client/views/nodes/WebView.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { FieldViewProps, FieldView } from "./FieldView"; -import { computed } from "mobx"; -import { observer } from "mobx-react"; -import { KeyStore } from "../../../fields/KeyStore"; -import React = require('react') -import { TextField } from "../../../fields/TextField"; -import { HtmlField } from "../../../fields/HtmlField"; -import { RichTextField } from "../../../fields/RichTextField"; - -@observer -export class WebView extends React.Component<FieldViewProps> { - public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(WebView, fieldStr) } - - @computed - get html(): string { - return this.props.doc.GetData(KeyStore.Data, HtmlField, "" as string); - } - - render() { - return <span dangerouslySetInnerHTML={{ __html: this.html }}></span> - } -}
\ No newline at end of file |
