From f7ae243462a819c69ee4ba9d828b69b3685a0e13 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 24 May 2019 17:54:30 -0400 Subject: restructured schemaView for performance/clarity --- .../views/collections/CollectionSchemaView.tsx | 193 ++++++++++++--------- 1 file changed, 114 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index b793447ff..1af13765b 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -2,7 +2,7 @@ import React = require("react"); import { library } from '@fortawesome/fontawesome-svg-core'; import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, untracked, runInAction } from "mobx"; +import { action, computed, observable, untracked, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table"; import { MAX_ROW_HEIGHT } from '../../views/globalCssVariables.scss'; @@ -27,8 +27,13 @@ import { Id } from "../../../new_fields/FieldSymbols"; import { Gateway } from "../../northstar/manager/Gateway"; import { Docs } from "../../documents/Documents"; import { ContextMenu } from "../ContextMenu"; +import { CollectionView } from "./CollectionView"; +import { CollectionPDFView } from "./CollectionPDFView"; +import { CollectionVideoView } from "./CollectionVideoView"; +library.add(faCog); +library.add(faPlus); // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 @@ -51,7 +56,7 @@ class KeyToggle extends React.Component<{ keyName: string, checked: boolean, tog @observer export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _mainCont?: HTMLDivElement; - private _startSplitPercent = 0; + private _startPreviewWidth = 0; private DIVIDER_WIDTH = 4; @observable _columns: Array = ["title", "data", "author"]; @@ -60,10 +65,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable _keys: string[] = []; @observable _newKeyName: string = ""; - @computed get splitPercentage() { return NumCast(this.props.Document.schemaSplitPercentage); } + @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } + @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } + @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); } @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } - @computed get tableColumns() { return this.columns.map(col => { const ref = React.createRef(); @@ -194,30 +200,31 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { //toggles preview side-panel of schema @action - toggleExpander = (event: React.ChangeEvent) => { - this.props.Document.schemaSplitPercentage = this.splitPercentage === 0 ? 33 : 0; + toggleExpander = () => { + this.props.Document.schemaPreviewWidth = this.previewWidth() === 0 ? Math.min(this.tableWidth / 3, 200) : 0; } + onDividerDown = (e: React.PointerEvent) => { + this._startPreviewWidth = this.previewWidth(); + e.stopPropagation(); + e.preventDefault(); + document.addEventListener("pointermove", this.onDividerMove); + document.addEventListener('pointerup', this.onDividerUp); + } @action onDividerMove = (e: PointerEvent): void => { let nativeWidth = this._mainCont!.getBoundingClientRect(); - this.props.Document.schemaSplitPercentage = Math.max(0, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100)); + this.props.Document.schemaPreviewWidth = Math.min(nativeWidth.right - nativeWidth.left - 40, + this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0]); } @action onDividerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onDividerMove); document.removeEventListener('pointerup', this.onDividerUp); - if (this._startSplitPercent === this.splitPercentage) { - this.props.Document.schemaSplitPercentage = this.splitPercentage === 0 ? 33 : 0; + if (this._startPreviewWidth === this.previewWidth()) { + this.toggleExpander(); } } - onDividerDown = (e: React.PointerEvent) => { - this._startSplitPercent = this.splitPercentage; - e.stopPropagation(); - e.preventDefault(); - document.addEventListener("pointermove", this.onDividerMove); - document.addEventListener('pointerup', this.onDividerUp); - } onPointerDown = (e: React.PointerEvent): void => { if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { @@ -270,63 +277,16 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this._newKeyName = e.currentTarget.value; } - @observable previewScript: string = ""; - @action - onPreviewScriptChange = (e: React.ChangeEvent) => { - this.previewScript = e.currentTarget.value; - } - @computed get previewDocument(): Doc | undefined { const children = DocListCast(this.props.Document[this.props.fieldKey]); const selected = children.length > this._selectedIndex ? FieldValue(children[this._selectedIndex]) : undefined; return selected ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; } - get tableWidth() { return (this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH) * (1 - this.splitPercentage / 100); } - get previewRegionHeight() { return this.props.PanelHeight() - 2 * this.borderWidth; } - get previewRegionWidth() { return (this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH) * this.splitPercentage / 100; } - - private previewDocNativeWidth = () => Cast(this.previewDocument!.nativeWidth, "number", this.previewRegionWidth); - private previewDocNativeHeight = () => Cast(this.previewDocument!.nativeHeight, "number", this.previewRegionHeight); - private previewContentScaling = () => { - let wscale = this.previewRegionWidth / (this.previewDocNativeWidth() ? this.previewDocNativeWidth() : this.previewRegionWidth); - if (wscale * this.previewDocNativeHeight() > this.previewRegionHeight) { - return this.previewRegionHeight / (this.previewDocNativeHeight() ? this.previewDocNativeHeight() : this.previewRegionHeight); - } - return wscale; - } - private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); - private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); - get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } + getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( - - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth - this.previewPanelCenteringOffset, - - this.borderWidth).scale(1 / this.previewContentScaling()) + - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth, - this.borderWidth); - @computed - get previewPanel() { - // let doc = CompileScript(this.previewScript, { this: selected }, true)(); - const previewDoc = this.previewDocument; - return (
- {!previewDoc || !this.previewRegionWidth ? (null) : ( -
- -
)} - -
); - } get documentKeysCheckList() { const docs = DocListCast(this.props.Document[this.props.fieldKey]); @@ -352,7 +312,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
Options
Preview Window
-
Show Preview
+
Show Preview
Displayed Columns
    {this.documentKeysCheckList} @@ -366,32 +326,107 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { ); } + @computed + get reactTable() { + trace(); + let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; + return + } + @computed get dividerDragger() { - return this.splitPercentage === 0 ? (null) : + return this.previewWidth() === 0 ? (null) :
    ; } - + @computed + get previewPanel() { + trace(); + return !this.previewDocument ? (null) : + } render() { - library.add(faCog); - library.add(faPlus); - const children = this.childDocs; + trace(); return (
    this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}> -
    - -
    + {this.reactTable} {this.dividerDragger} - {this.previewPanel} + {!this.previewWidth() ? (null) : this.previewPanel} {this.tableOptionsPanel}
    ); } +} +interface CollectionSchemaPreviewProps { + Document: Doc; + width: () => number; + height: () => number; + CollectionView: CollectionView | CollectionPDFView | CollectionVideoView; + getTransform: () => Transform; + addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; + removeDocument: (document: Doc) => boolean; + active: () => boolean; + whenActiveChanged: (isActive: boolean) => void; + addDocTab: (document: Doc, where: string) => void; +} + +@observer +class CollectionSchemaPreview extends React.Component{ + @observable previewScript: string = ""; + private get nativeWidth() { return NumCast(this.props.Document.nativeWidth, this.props.width()); } + private get nativeHeight() { return NumCast(this.props.Document.nativeHeight, this.props.height()); } + private contentScaling = () => { + let wscale = this.props.width() / (this.nativeWidth ? this.nativeWidth : this.props.width()); + if (wscale * this.nativeHeight > this.props.height()) { + return this.props.height() / (this.nativeHeight ? this.nativeHeight : this.props.height()); + } + return wscale; + } + private PanelWidth = () => this.nativeWidth * this.contentScaling(); + private PanelHeight = () => this.nativeHeight * this.contentScaling(); + private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling()) + get centeringOffset() { return (this.props.width() - this.nativeWidth * this.contentScaling()) / 2; } + @action + onPreviewScriptChange = (e: React.ChangeEvent) => { + this.previewScript = e.currentTarget.value; + } + render() { + trace(); + return (
    + {!this.props.Document || !this.props.width ? (null) : ( +
    + +
    )} + +
    ); + } } \ No newline at end of file -- cgit v1.2.3-70-g09d2