diff options
author | bob <bcz@cs.brown.edu> | 2019-02-04 10:44:30 -0500 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-02-04 10:44:30 -0500 |
commit | e79e53d78546501fc855b76a84f000289ed7433a (patch) | |
tree | 80d3309086d31d95a139933be237842d3c3ee796 | |
parent | 6539a76c8fae1fa816bde4d9e094eb074d1a68b8 (diff) |
split out common code into CollectionViewBase. organized a few other things, too.
-rw-r--r-- | src/views/collections/CollectionDockingView.tsx | 37 | ||||
-rw-r--r-- | src/views/collections/CollectionFreeFormView.tsx | 37 | ||||
-rw-r--r-- | src/views/collections/CollectionSchemaView.tsx | 19 | ||||
-rw-r--r-- | src/views/collections/CollectionViewBase.tsx | 53 | ||||
-rw-r--r-- | src/views/nodes/DocumentView.tsx | 31 | ||||
-rw-r--r-- | src/views/nodes/FieldTextBox.tsx | 10 | ||||
-rw-r--r-- | src/views/nodes/FieldView.tsx | 17 | ||||
-rw-r--r-- | src/views/nodes/ImageBox.tsx | 13 |
8 files changed, 96 insertions, 121 deletions
diff --git a/src/views/collections/CollectionDockingView.tsx b/src/views/collections/CollectionDockingView.tsx index 8c8238ee0..177e3510a 100644 --- a/src/views/collections/CollectionDockingView.tsx +++ b/src/views/collections/CollectionDockingView.tsx @@ -4,21 +4,20 @@ import React = require("react"); import FlexLayout from "flexlayout-react"; import { action, observable, computed } from "mobx"; import { Document } from "../../fields/Document"; -import { DocumentView, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "../nodes/DocumentView"; +import { DocumentView } from "../nodes/DocumentView"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { SSL_OP_SINGLE_DH_USE } from "constants"; -import { SelectionManager } from "../../util/SelectionManager"; -import { ContextMenu } from "../ContextMenu"; import "./CollectionDockingView.scss" import 'golden-layout/src/css/goldenlayout-base.css'; 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"; @observer -export class CollectionDockingView extends React.Component<CollectionViewProps> { +export class CollectionDockingView extends CollectionViewBase { private static UseGoldenLayout = true; public static LayoutString() { return '<CollectionDockingView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>'; } @@ -56,14 +55,6 @@ export class CollectionDockingView extends React.Component<CollectionViewProps> super(props); } - @computed - public get active(): boolean { - var isSelected = (this.props.ContainingDocumentView != undefined && SelectionManager.IsSelected(this.props.ContainingDocumentView)); - var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); - var topMost = this.props.ContainingDocumentView != undefined && this.props.ContainingDocumentView.props.ContainingCollectionView == undefined; - return isSelected || childSelected || topMost; - } - componentDidMount: () => void = () => { if (this._containerRef.current && CollectionDockingView.UseGoldenLayout) { this.goldenLayoutFactory(); @@ -75,24 +66,6 @@ export class CollectionDockingView extends React.Component<CollectionViewProps> } private nextId = (function () { var _next_id = 0; return function () { return _next_id++; } })(); - @action - addDocument = (doc: Document): void => { - //TODO This won't create the field if it doesn't already exist - const value = this.props.Document.GetFieldValue(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.Document.GetFieldValue(this.props.fieldKey, ListField, new Array<Document>()) - if (value.indexOf(doc) !== -1) { - value.splice(value.indexOf(doc), 1) - - SelectionManager.DeselectAll() - ContextMenu.Instance.clearItems() - } - } @action onResize = (event: any) => { @@ -167,11 +140,11 @@ export class CollectionDockingView extends React.Component<CollectionViewProps> _makeFullScreen: boolean = false; _maximizedStack: any = null; - public static OpenFullScreen(dv: DocumentView) { + public static OpenFullScreen(document: Document) { var newItemConfig = { type: 'component', componentName: 'documentViewComponent', - componentState: { doc: dv.props.Document } + componentState: { doc: document } }; CollectionDockingView.myLayout._makeFullScreen = true; CollectionDockingView.myLayout.root.contentItems[0].addChild(newItemConfig); diff --git a/src/views/collections/CollectionFreeFormView.tsx b/src/views/collections/CollectionFreeFormView.tsx index 403dbf503..ab2aeee64 100644 --- a/src/views/collections/CollectionFreeFormView.tsx +++ b/src/views/collections/CollectionFreeFormView.tsx @@ -3,20 +3,18 @@ import { Key, KeyStore } from "../../fields/Key"; import React = require("react"); import { action, observable, computed } from "mobx"; import { Document } from "../../fields/Document"; -import { DocumentView, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "../nodes/DocumentView"; +import { DocumentView } from "../nodes/DocumentView"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { SSL_OP_SINGLE_DH_USE } from "constants"; -import { SelectionManager } from "../../util/SelectionManager"; import { Documents } from "../../documents/Documents"; -import { ContextMenu } from "../ContextMenu"; import { DragManager } from "../../util/DragManager"; import "./CollectionFreeFormView.scss"; import { Utils } from "../../Utils"; -import { CollectionDockingView } from "./CollectionDockingView"; +import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; @observer -export class CollectionFreeFormView extends React.Component<CollectionViewProps> { +export class CollectionFreeFormView extends CollectionViewBase { private _containerRef = React.createRef<HTMLDivElement>(); private _canvasRef = React.createRef<HTMLDivElement>(); private _nodeContainerRef = React.createRef<HTMLDivElement>(); @@ -27,16 +25,6 @@ export class CollectionFreeFormView extends React.Component<CollectionViewProps> super(props); } - @computed - public get active(): boolean { - var isSelected = (this.props.ContainingDocumentView != undefined && SelectionManager.IsSelected(this.props.ContainingDocumentView)); - 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); - return isSelected || childSelected || topMost; - } - @action drop = (e: Event, de: DragManager.DropEvent) => { const doc = de.data["document"]; @@ -159,25 +147,6 @@ export class CollectionFreeFormView extends React.Component<CollectionViewProps> } @action - addDocument = (doc: Document): void => { - //TODO This won't create the field if it doesn't already exist - const value = this.props.Document.GetFieldValue(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.Document.GetFieldValue(this.props.fieldKey, ListField, new Array<Document>()) - if (value.indexOf(doc) !== -1) { - value.splice(value.indexOf(doc), 1) - - SelectionManager.DeselectAll() - ContextMenu.Instance.clearItems() - } - } - - @action bringToFront(doc: DocumentView) { const { fieldKey, Document: Document } = this.props; diff --git a/src/views/collections/CollectionSchemaView.tsx b/src/views/collections/CollectionSchemaView.tsx index dd33958dc..420a68cc9 100644 --- a/src/views/collections/CollectionSchemaView.tsx +++ b/src/views/collections/CollectionSchemaView.tsx @@ -1,19 +1,19 @@ -import { CollectionViewProps, DocumentFieldViewProps, DocumentView, DocumentContents } from "../nodes/DocumentView"; +import { DocumentContents } from "../nodes/DocumentView"; import React = require("react") import ReactTable, { ReactTableDefaults, CellInfo, ComponentPropsGetterRC, ComponentPropsGetterR } from "react-table"; import { observer } from "mobx-react"; import { KeyStore as KS, Key } from "../../fields/Key"; import { Document } from "../../fields/Document"; -import { FieldView } from "../nodes/FieldView"; +import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "react-table/react-table.css" import { observable, action, computed } from "mobx"; import SplitPane from "react-split-pane" import "./CollectionSchemaView.scss" import { ScrollBox } from "../../util/ScrollBox"; -import { SelectionManager } from "../../util/SelectionManager"; +import { CollectionViewBase } from "./CollectionViewBase"; @observer -export class CollectionSchemaView extends React.Component<CollectionViewProps> { +export class CollectionSchemaView extends CollectionViewBase { public static LayoutString() { return '<CollectionSchemaView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>'; } @observable @@ -23,10 +23,10 @@ export class CollectionSchemaView extends React.Component<CollectionViewProps> { if (!this.props.ContainingDocumentView) { return <div></div> } - let props: DocumentFieldViewProps = { + let props: FieldViewProps = { doc: rowProps.value[0], fieldKey: rowProps.value[1], - containingDocumentView: this.props.ContainingDocumentView + documentViewContainer: this.props.ContainingDocumentView } return ( <FieldView {...props} /> @@ -55,13 +55,6 @@ export class CollectionSchemaView extends React.Component<CollectionViewProps> { }; } - @computed - public get active(): boolean { - var isSelected = (this.props.ContainingDocumentView != undefined && SelectionManager.IsSelected(this.props.ContainingDocumentView)); - var childSelected = false; // SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); - var topMost = this.props.ContainingDocumentView != undefined && this.props.ContainingDocumentView.props.ContainingCollectionView == undefined; - return isSelected || childSelected || topMost; - } onPointerDown = (e: React.PointerEvent) => { let target = e.target as HTMLElement; if (target.tagName == "SPAN" && target.className.includes("Resizer")) { diff --git a/src/views/collections/CollectionViewBase.tsx b/src/views/collections/CollectionViewBase.tsx new file mode 100644 index 000000000..bfded71d9 --- /dev/null +++ b/src/views/collections/CollectionViewBase.tsx @@ -0,0 +1,53 @@ +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 { ListField } from "../../fields/ListField"; +import { SelectionManager } from "../../util/SelectionManager"; +import { ContextMenu } from "../ContextMenu"; +import React = require("react"); +import { DocumentView } from "../nodes/DocumentView"; +import { CollectionDockingView } from "./CollectionDockingView"; + + +export interface CollectionViewProps { + fieldKey: Key; + Document: Document; + ContainingDocumentView: Opt<DocumentView>; +} + +export const COLLECTION_BORDER_WIDTH = 2; + +@observer +export class CollectionViewBase extends React.Component<CollectionViewProps> { + + @computed + public get active(): boolean { + var isSelected = (this.props.ContainingDocumentView != undefined && SelectionManager.IsSelected(this.props.ContainingDocumentView)); + 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); + 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.Document.GetFieldValue(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.Document.GetFieldValue(this.props.fieldKey, ListField, new Array<Document>()) + if (value.indexOf(doc) !== -1) { + value.splice(value.indexOf(doc), 1) + + SelectionManager.DeselectAll() + ContextMenu.Instance.clearItems() + } + } + +}
\ No newline at end of file diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index 9e8df0d79..dd47d4455 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -11,6 +11,7 @@ import "./NodeView.scss" import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Utils } from "../../Utils"; +import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { ContextMenu } from "../ContextMenu"; @@ -22,35 +23,9 @@ const JsxParser = require('react-jsx-parser').default;//TODO Why does this need interface DocumentViewProps { Document: Document; - ContainingCollectionView: Opt<CollectionView>; + ContainingCollectionView: Opt<CollectionViewBase>; ContainingDocumentView: Opt<DocumentView>; } - -export interface CollectionViewProps { - fieldKey: Key; - Document: Document; - ContainingDocumentView: Opt<DocumentView>; -} - -// -// these properties get assigned through the render() method of the DocumentView when it creates this node. -// However, that only happens because the properties are "defined" in FieldTextBox's LayoutString() method -// -export interface DocumentFieldViewProps { - fieldKey: Key; - doc: Document; - containingDocumentView: DocumentView -} - -export const COLLECTION_BORDER_WIDTH = 2; - -interface CollectionView { - addDocument: (doc: Document) => void; - removeDocument: (doc: Document) => void; - active: boolean; - props: CollectionViewProps; -} - @observer export class DocumentContents extends React.Component<DocumentViewProps> { @@ -325,7 +300,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { } @action fullScreenClicked = (e: React.MouseEvent): void => { - CollectionDockingView.OpenFullScreen(this); + CollectionDockingView.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) diff --git a/src/views/nodes/FieldTextBox.tsx b/src/views/nodes/FieldTextBox.tsx index 1e03bf0f9..188b39a17 100644 --- a/src/views/nodes/FieldTextBox.tsx +++ b/src/views/nodes/FieldTextBox.tsx @@ -9,10 +9,10 @@ import { Document } from "../../fields/Document"; import { Opt } from "../../fields/Field"; import { Key } from "../../fields/Key"; import { SelectionManager } from "../../util/SelectionManager"; -import { DocumentView, DocumentFieldViewProps } from "./DocumentView"; import "./FieldTextBox.scss"; import React = require("react") import { RichTextField } from "../../fields/RichTextField"; +import { FieldViewProps } from "./FieldView"; // FieldTextBox: Displays an editable plain text node that maps to a specified Key of a Document @@ -31,14 +31,14 @@ import { RichTextField } from "../../fields/RichTextField"; // specified Key and assigns it to an HTML input node. When changes are made tot his node, // this will edit the document and assign the new value to that field. // -export class FieldTextBox extends React.Component<DocumentFieldViewProps> { +export class FieldTextBox extends React.Component<FieldViewProps> { - public static LayoutString() { return "<FieldTextBox doc={Document} containingDocumentView={ContainingDocumentView} fieldKey={DataKey} />"; } + public static LayoutString() { return "<FieldTextBox doc={Document} documentViewContainer={ContainingDocumentView} fieldKey={DataKey} />"; } private _ref: React.RefObject<HTMLDivElement>; private _editorView: Opt<EditorView>; private _reactionDisposer: Opt<IReactionDisposer>; - constructor(props: DocumentFieldViewProps) { + constructor(props: FieldViewProps) { super(props); this._ref = React.createRef(); @@ -110,7 +110,7 @@ export class FieldTextBox extends React.Component<DocumentFieldViewProps> { } onPointerDown = (e: React.PointerEvent): void => { let me = this; - if (e.buttons === 1 && SelectionManager.IsSelected(me.props.containingDocumentView)) { + if (e.buttons === 1 && SelectionManager.IsSelected(me.props.documentViewContainer)) { e.stopPropagation(); } } diff --git a/src/views/nodes/FieldView.tsx b/src/views/nodes/FieldView.tsx index eec63256d..6c1cd956b 100644 --- a/src/views/nodes/FieldView.tsx +++ b/src/views/nodes/FieldView.tsx @@ -1,5 +1,6 @@ import React = require("react") -import { DocumentFieldViewProps } from "./DocumentView"; +import { DocumentView } from "./DocumentView"; +import { Document } from "../../fields/Document"; import { observer } from "mobx-react"; import { computed } from "mobx"; import { Field, Opt } from "../../fields/Field"; @@ -9,9 +10,21 @@ import { RichTextField } from "../../fields/RichTextField"; import { FieldTextBox } from "./FieldTextBox"; import { ImageField } from "../../fields/ImageField"; import { ImageBox } from "./ImageBox"; +import { Key } from "../../fields/Key"; + +// +// these properties get assigned through the render() method of the DocumentView when it creates this node. +// However, that only happens because the properties are "defined" in the markup for the field view. +// See the LayoutString method on each field view : ImageBox, FieldTextBox, etc. +// +export interface FieldViewProps { + fieldKey: Key; + doc: Document; + documentViewContainer: DocumentView +} @observer -export class FieldView extends React.Component<DocumentFieldViewProps> { +export class FieldView extends React.Component<FieldViewProps> { @computed get field(): Opt<Field> { const { doc, fieldKey } = this.props; diff --git a/src/views/nodes/ImageBox.tsx b/src/views/nodes/ImageBox.tsx index 7577627e8..5137dbf38 100644 --- a/src/views/nodes/ImageBox.tsx +++ b/src/views/nodes/ImageBox.tsx @@ -2,26 +2,25 @@ import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app import { SelectionManager } from "../../util/SelectionManager"; -import { DocumentFieldViewProps } from "./DocumentView"; import "./ImageBox.scss"; import React = require("react") import { ImageField } from '../../fields/ImageField'; -import { NumberField } from '../../fields/NumberField'; +import { FieldViewProps } from './FieldView'; interface ImageBoxState { photoIndex: number, isOpen: boolean, }; -export class ImageBox extends React.Component<DocumentFieldViewProps, ImageBoxState> { +export class ImageBox extends React.Component<FieldViewProps, ImageBoxState> { - public static LayoutString() { return "<ImageBox doc={Document} containingDocumentView={ContainingDocumentView} fieldKey={DataKey} />"; } + public static LayoutString() { return "<ImageBox doc={Document} documentViewContainer={ContainingDocumentView} fieldKey={DataKey} />"; } private _ref: React.RefObject<HTMLDivElement>; private _downX: number = 0; private _downY: number = 0; private _lastTap: number = 0; - constructor(props: DocumentFieldViewProps) { + constructor(props: FieldViewProps) { super(props); this._ref = React.createRef(); @@ -39,7 +38,7 @@ export class ImageBox extends React.Component<DocumentFieldViewProps, ImageBoxSt onPointerDown = (e: React.PointerEvent): void => { if (Date.now() - this._lastTap < 300) { - if (e.buttons === 1 && SelectionManager.IsSelected(this.props.containingDocumentView)) { + if (e.buttons === 1 && SelectionManager.IsSelected(this.props.documentViewContainer)) { e.stopPropagation(); this._downX = e.clientX; this._downY = e.clientY; @@ -67,7 +66,7 @@ export class ImageBox extends React.Component<DocumentFieldViewProps, ImageBoxSt const images = [path,]; var lightbox = () => { const { photoIndex } = this.state; - if (this.state.isOpen && SelectionManager.IsSelected(this.props.containingDocumentView)) { + if (this.state.isOpen && SelectionManager.IsSelected(this.props.documentViewContainer)) { return (<Lightbox mainSrc={images[photoIndex]} nextSrc={photoIndex + 1 < images.length ? images[(photoIndex + 1) % images.length] : undefined} |