diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 47 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.scss | 70 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.tsx | 69 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValuePair.tsx | 31 |
5 files changed, 184 insertions, 37 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 54afda8f3..76127a7f3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -14,20 +14,21 @@ import { Transform } from "../../util/Transform"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; import { ContextMenu } from "../ContextMenu"; -import {FormattedTextBox} from "../nodes/FormattedTextBox" -import {ImageBox} from "../nodes/ImageBox"; -import {CollectionFreeFormView} from "../collections/CollectionFreeFormView" -import {PDFBox} from "../nodes/PDFBox"; -import {WebBox} from "../nodes/WebBox" -import {CollectionSchemaView} from "../collections/CollectionSchemaView" -import {AudioBox} from "../nodes/AudioBox"; -import {VideoBox} from "../nodes/VideoBox"; -import {CollectionPDFView} from "../collections/CollectionPDFView" -import {CollectionVideoView} from "../collections/CollectionVideoView" -import {KeyValueBox} from "../nodes/KeyValueBox" +import { FormattedTextBox } from "../nodes/FormattedTextBox" +import { ImageBox } from "../nodes/ImageBox"; +import { CollectionFreeFormView } from "../collections/CollectionFreeFormView" +import { PDFBox } from "../nodes/PDFBox"; +import { WebBox } from "../nodes/WebBox" +import { CollectionSchemaView } from "../collections/CollectionSchemaView" +import { AudioBox } from "../nodes/AudioBox"; +import { VideoBox } from "../nodes/VideoBox"; +import { CollectionPDFView } from "../collections/CollectionPDFView" +import { CollectionVideoView } from "../collections/CollectionVideoView" +import { KeyValueBox } from "../nodes/KeyValueBox" import "./DocumentView.scss"; import React = require("react"); import { DocumentContentsView } from "./DocumentContentsView"; +import { Utils } from "../../../Utils"; import { faUserPlus } from "@fortawesome/free-solid-svg-icons"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -243,6 +244,9 @@ export class DocumentView extends React.Component<DocumentViewProps> { SelectionManager.SelectDoc(this, e.ctrlKey); } } + stopPropogation = (e: React.SyntheticEvent) => { + e.stopPropagation(); + } deleteClicked = (): void => { if (this.props.RemoveDocument) { @@ -295,6 +299,20 @@ export class DocumentView extends React.Component<DocumentViewProps> { e.stopPropagation(); } + onDrop = (e: React.DragEvent) => { + if (e.isDefaultPrevented()) { + return; + } + let text = e.dataTransfer.getData("text/plain"); + if (text && text.startsWith("<div")) { + let oldLayout = this.props.Document.GetText(KeyStore.Layout, ""); + let layout = text.replace("{layout}", oldLayout); + this.props.Document.SetText(KeyStore.Layout, layout); + e.stopPropagation(); + e.preventDefault(); + } + } + @action onContextMenu = (e: React.MouseEvent): void => { e.stopPropagation(); @@ -309,6 +327,12 @@ export class DocumentView extends React.Component<DocumentViewProps> { 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: "Copy ID", + event: () => { + Utils.CopyText(this.props.Document.Id); + } + }); //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) { @@ -351,6 +375,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { transformOrigin: "left top", transform: `scale(${scaling} , ${scaling})` }} + onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} > <DocumentContents {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={KeyStore.Layout} /> diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index f5d4c030b..d7026ed67 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -14,6 +14,9 @@ import { Plugin } from 'prosemirror-state' import { Decoration, DecorationSet } from 'prosemirror-view' import { TooltipTextMenu } from "../../util/TooltipTextMenu" import { ContextMenu } from "../../views/ContextMenu"; +import { inpRules } from "../../util/RichTextRules"; +const { buildMenuItems } = require("prosemirror-example-setup"); +const { menuBar } = require("prosemirror-menu"); @@ -60,6 +63,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { let state: EditorState; const config = { schema, + inpRules, //these currently don't do anything, but could eventually be helpful plugins: [ history(), keymap({ "Mod-z": undo, "Mod-y": redo }), diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss index e946275fa..63ae75424 100644 --- a/src/client/views/nodes/KeyValueBox.scss +++ b/src/client/views/nodes/KeyValueBox.scss @@ -1,31 +1,57 @@ +@import "../global_variables"; .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; - } + overflow-y: scroll; + height: 100%; + background-color: $light-color; + border: 1px solid $intermediate-color; + border-radius: $border-radius; + box-sizing: border-box; + display: inline-block; + .imageBox-cont img { + max-height: 45px; + height: auto; + } + td { + padding: 6px 8px; + border-right: 1px solid $intermediate-color; + border-top: 1px solid $intermediate-color; + &:last-child { + border-right: none; + } + } } + .keyValueBox-table { - position: relative; + position: relative; + border-collapse: collapse; } + .keyValueBox-header { - background: gray; + background: $intermediate-color; + color: $light-color; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 12px; + height: 30px; + padding-top: 4px; + th { + font-weight: normal; + &:first-child { + border-right: 1px solid $light-color; + } + } } + .keyValueBox-evenRow { - background: white; - .formattedTextBox-cont { - background: white; - } + background: $light-color; + .formattedTextBox-cont { + background: $light-color; + } } + .keyValueBox-oddRow { - background: lightGray; - .formattedTextBox-cont { - background: lightgray; - } -} + background: $light-color-secondary; + .formattedTextBox-cont { + background: $light-color-secondary; + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index ac8c949a9..283c1f732 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -2,17 +2,62 @@ import { observer } from "mobx-react"; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app import { Document } from '../../../fields/Document'; -import { FieldWaiting } from '../../../fields/Field'; +import { FieldWaiting, Field } from '../../../fields/Field'; import { KeyStore } from '../../../fields/KeyStore'; import { FieldView, FieldViewProps } from './FieldView'; import "./KeyValueBox.scss"; import { KeyValuePair } from "./KeyValuePair"; import React = require("react") +import { CompileScript, ToField } from "../../util/Scripting"; +import { Key } from '../../../fields/Key'; +import { observable, action } from "mobx"; @observer export class KeyValueBox extends React.Component<FieldViewProps> { public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(KeyValueBox, fieldStr) } + @observable private _keyInput: string = ""; + @observable private _valueInput: string = ""; + + + constructor(props: FieldViewProps) { + super(props); + } + + + + shouldComponentUpdate() { + return false; + } + + @action + onEnterKey = (e: React.KeyboardEvent): void => { + if (e.key == 'Enter') { + if (this._keyInput && this._valueInput) { + let doc = this.props.doc.GetT(KeyStore.Data, Document); + if (!doc || doc == FieldWaiting) { + return + } + let realDoc = doc; + + let script = CompileScript(this._valueInput, undefined, true); + if (!script.compiled) { + return; + } + let field = script(); + if (field instanceof Field) { + realDoc.Set(new Key(this._keyInput), field); + } else { + let dataField = ToField(field); + if (dataField) { + realDoc.Set(new Key(this._keyInput), dataField); + } + } + this._keyInput = "" + this._valueInput = "" + } + } + } onPointerDown = (e: React.PointerEvent): void => { if (e.buttons === 1 && this.props.isSelected()) { @@ -33,7 +78,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> { let ids: { [key: string]: string } = {}; let protos = doc.GetAllPrototypes(); for (const proto of protos) { - proto._proxies.forEach((val, key) => { + proto._proxies.forEach((val: any, key: string) => { if (!(key in ids)) { ids[key] = key; } @@ -48,9 +93,26 @@ export class KeyValueBox extends React.Component<FieldViewProps> { return rows; } + @action + keyChanged = (e: React.ChangeEvent<HTMLInputElement>) => { + this._keyInput = e.currentTarget.value; + } + + @action + valueChanged = (e: React.ChangeEvent<HTMLInputElement>) => { + this._valueInput = e.currentTarget.value; + } - render() { + newKeyValue = () => { + return ( + <tr> + <td><input type="text" value={this._keyInput} placeholder="Key" onChange={this.keyChanged} /></td> + <td><input type="text" value={this._valueInput} placeholder="Value" onChange={this.valueChanged} onKeyPress={this.onEnterKey} /></td> + </tr> + ) + } + render() { return (<div className="keyValueBox-cont" onWheel={this.onPointerWheel}> <table className="keyValueBox-table"> <tbody> @@ -59,6 +121,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> { <th>Fields</th> </tr> {this.createTable()} + {this.newKeyValue()} </tbody> </table> </div>) diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index a97e98313..111f85a05 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -8,6 +8,8 @@ import { observable, action } from 'mobx'; import { Document } from '../../../fields/Document'; import { Key } from '../../../fields/Key'; import { Server } from "../../Server" +import { EditableView } from "../EditableView"; +import { CompileScript, ToField } from "../../util/Scripting"; // Represents one row in a key value plane @@ -48,10 +50,37 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> { bindings: {}, selectOnLoad: false, } + let contents = ( + <FieldView {...props} /> + ); return ( <tr className={this.props.rowStyle}> <td>{this.key.Name}</td> - <td><FieldView {...props} /></td> + <td><EditableView contents={contents} height={36} GetValue={() => { + let field = props.doc.Get(props.fieldKey); + if (field && field instanceof Field) { + return field.ToScriptString(); + } + return field || ""; + }} + SetValue={(value: string) => { + let script = CompileScript(value, undefined, true); + if (!script.compiled) { + return false; + } + let field = script(); + if (field instanceof Field) { + props.doc.Set(props.fieldKey, field); + return true; + } else { + let dataField = ToField(field); + if (dataField) { + props.doc.Set(props.fieldKey, dataField); + return true; + } + } + return false; + }}></EditableView></td> </tr> ) } |
