diff options
| author | laurawilsonri <laura_wilson@brown.edu> | 2019-03-18 18:14:27 -0400 |
|---|---|---|
| committer | laurawilsonri <laura_wilson@brown.edu> | 2019-03-18 18:14:27 -0400 |
| commit | 9d939c1190ef86e456cf26e9f5cb84743279f7a6 (patch) | |
| tree | 24d72d918f2becf6762ea30b92da7339957eedbd /src/client/views/collections/CollectionSchemaView.tsx | |
| parent | 67170e521366f8178645cc85aaf377e53b1a6f21 (diff) | |
| parent | f70ad315167b714f11f7d68f35a46abe9e525a4d (diff) | |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into editableSchema
Diffstat (limited to 'src/client/views/collections/CollectionSchemaView.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 230 |
1 files changed, 188 insertions, 42 deletions
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 7c87ef744..2598dd3a9 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -1,11 +1,16 @@ +<<<<<<< HEAD import React = require("react"); import { action, observable } from "mobx"; +======= +import React = require("react") +import { action, observable, ObservableMap, computed } from "mobx"; +>>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d import { observer } from "mobx-react"; import Measure from "react-measure"; import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table"; import "react-table/react-table.css"; import { Document } from "../../../fields/Document"; -import { Field } from "../../../fields/Field"; +import { Field, Opt } from "../../../fields/Field"; import { KeyStore } from "../../../fields/KeyStore"; import { CompileScript, ToField } from "../../util/Scripting"; import { Transform } from "../../util/Transform"; @@ -14,9 +19,10 @@ import { EditableView } from "../EditableView"; import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; -import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; +import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView"; import { CollectionViewBase } from "./CollectionViewBase"; import { setupDrag } from "../../util/DragManager"; +<<<<<<< HEAD import '../DocumentDecorations.scss'; import { Flyout, anchorPoints } from "../DocumentDecorations"; import { DropdownButton, Dropdown } from 'react-bootstrap'; @@ -27,21 +33,53 @@ import { Key } from "../../../fields/Key"; import { Server } from "../../Server"; //import { MenuItem } from 'react-bootstrap'; +======= +import { Key } from "./../../../fields/Key"; +import { Server } from "../../Server"; +import { ListField } from "../../../fields/ListField"; + +>>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 @observer +class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggle: (key: Key) => void }> { + @observable + key: Key | undefined; + + componentWillReceiveProps() { + Server.GetField(this.props.keyId, action((field: Opt<Field>) => { + if (field instanceof Key) { + this.key = field; + } + })) + } + + render() { + if (this.key) { + return (<div key={this.key.Id}> + <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />{this.key.Name} + </div>) + } else { + return <div></div> + } + } +} + +@observer export class CollectionSchemaView extends CollectionViewBase { private _mainCont = React.createRef<HTMLDivElement>(); - private DIVIDER_WIDTH = 5; + private DIVIDER_WIDTH = 4; + @observable _columns: Array<Key> = [KeyStore.Title, KeyStore.Data, KeyStore.Author]; @observable _contentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ContentScaling prop of the DocumentView @observable _dividerX = 0; @observable _panelWidth = 0; @observable _panelHeight = 0; @observable _selectedIndex = 0; - @observable _splitPercentage: number = 50; + @observable _columnsPercentage = 0; + @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); } renderCell = (rowProps: CellInfo) => { let props: FieldViewProps = { @@ -57,10 +95,12 @@ export class CollectionSchemaView extends CollectionViewBase { <FieldView {...props} /> ) let reference = React.createRef<HTMLDivElement>(); - let onItemDown = setupDrag(reference, () => props.doc); + let onItemDown = setupDrag(reference, () => props.doc, (containingCollection: CollectionView) => this.props.removeDocument(props.doc)); return ( - <div onPointerDown={onItemDown} key={props.doc.Id} ref={reference}> - <EditableView contents={contents} + <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}> + <EditableView + display={"inline"} + contents={contents} height={36} GetValue={() => { let field = props.doc.Get(props.fieldKey); if (field && field instanceof Field) { @@ -69,7 +109,7 @@ export class CollectionSchemaView extends CollectionViewBase { return field || ""; }} SetValue={(value: string) => { - let script = CompileScript(value, undefined, true); + let script = CompileScript(value); if (!script.compiled) { return false; } @@ -99,7 +139,8 @@ export class CollectionSchemaView extends CollectionViewBase { return { onClick: action((e: React.MouseEvent, handleOriginal: Function) => { that._selectedIndex = rowInfo.index; - this._splitPercentage += 0.05; // bcz - ugh - needed to force Measure to do its thing and call onResize + // bcz - ugh - needed to force Measure to do its thing and call onResize + this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage - 0.05) if (handleOriginal) { handleOriginal() @@ -112,27 +153,83 @@ export class CollectionSchemaView extends CollectionViewBase { }; } + get columns() { + return this.props.Document.GetList<Key>(KeyStore.ColumnsKey, []); + } + + @action + toggleKey = (key: Key) => { + this.props.Document.GetOrCreateAsync<ListField<Key>>(KeyStore.ColumnsKey, ListField, + (field) => { + const index = field.Data.indexOf(key); + if (index === -1) { + this.columns.push(key); + } else { + this.columns.splice(index, 1); + } + + }) + } + + @observable keys: Key[] = []; + + findAllDocumentKeys = (): { [id: string]: boolean } => { + const docs = this.props.Document.GetList<Document>(this.props.fieldKey, []); + let keys: { [id: string]: boolean } = {} + docs.forEach(doc => { + let protos = doc.GetAllPrototypes(); + for (const proto of protos) { + proto._proxies.forEach((val: any, key: string) => { + keys[key] = false + }) + } + }) + this.columns.forEach(key => { + keys[key.Id] = true; + }) + return keys; + } + _startSplitPercent = 0; @action onDividerMove = (e: PointerEvent): void => { let nativeWidth = this._mainCont.current!.getBoundingClientRect(); - this._splitPercentage = Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100); + this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100)); } @action onDividerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onDividerMove); document.removeEventListener('pointerup', this.onDividerUp); - if (this._startSplitPercent == this._splitPercentage) { - this._splitPercentage = this._splitPercentage == 1 ? 66 : 100; + if (this._startSplitPercent == this.splitPercentage) { + this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0); } } onDividerDown = (e: React.PointerEvent) => { - this._startSplitPercent = this._splitPercentage; + this._startSplitPercent = this.splitPercentage; e.stopPropagation(); e.preventDefault(); document.addEventListener("pointermove", this.onDividerMove); document.addEventListener('pointerup', this.onDividerUp); } + + + @action + onColDividerMove = (e: PointerEvent): void => { + let nativeWidth = this._mainCont.current!.getBoundingClientRect(); + this._columnsPercentage = 100 - (e.clientY - nativeWidth.top) / nativeWidth.height * 100; + } + @action + onColDividerUp = (e: PointerEvent): void => { + document.removeEventListener("pointermove", this.onColDividerMove); + document.removeEventListener('pointerup', this.onColDividerUp); + } + onColDividerDown = (e: React.PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + document.addEventListener("pointermove", this.onColDividerMove); + document.addEventListener('pointerup', this.onColDividerUp); + } + @action onExpanderMove = (e: PointerEvent): void => { e.stopPropagation(); @@ -144,12 +241,12 @@ export class CollectionSchemaView extends CollectionViewBase { e.preventDefault(); document.removeEventListener("pointermove", this.onExpanderMove); document.removeEventListener('pointerup', this.onExpanderUp); - if (this._startSplitPercent == this._splitPercentage) { - this._splitPercentage = this._splitPercentage == 100 ? 66 : 100; + if (this._startSplitPercent == this.splitPercentage) { + this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0); } } onExpanderDown = (e: React.PointerEvent) => { - this._startSplitPercent = this._splitPercentage; + this._startSplitPercent = this.splitPercentage; e.stopPropagation(); e.preventDefault(); document.addEventListener("pointermove", this.onExpanderMove); @@ -162,15 +259,36 @@ export class CollectionSchemaView extends CollectionViewBase { // e.preventDefault(); // } else { - if (e.buttons === 1) { - if (this.props.isSelected()) { - e.stopPropagation(); - } - } + // if (e.buttons === 1) { + // if (this.props.isSelected()) { + // e.stopPropagation(); + // } + // } } } @action + onColumnsMove = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + } + @action + onColumnsUp = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + document.removeEventListener("pointermove", this.onColumnsMove); + document.removeEventListener('pointerup', this.onColumnsUp); + this._columnsPercentage = this._columnsPercentage ? 0 : 50; + } + onColumnsDown = (e: React.PointerEvent) => { + this._startSplitPercent = this.splitPercentage; + e.stopPropagation(); + e.preventDefault(); + document.addEventListener("pointermove", this.onColumnsMove); + document.addEventListener('pointerup', this.onColumnsUp); + } + + @action setScaling = (r: any) => { const children = this.props.Document.GetList<Document>(this.props.fieldKey, []); const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; @@ -202,9 +320,10 @@ export class CollectionSchemaView extends CollectionViewBase { } render() { - const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author]) + const columns = this.columns; const children = this.props.Document.GetList<Document>(this.props.fieldKey, []); const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; + const allKeys = this.findAllDocumentKeys(); let content = this._selectedIndex == -1 || !selected ? (null) : ( <Measure onResize={this.setScaling}> {({ measureRef }) => @@ -226,8 +345,11 @@ export class CollectionSchemaView extends CollectionViewBase { ) let previewHandle = !this.props.active() ? (null) : ( <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />); - let dividerDragger = this._splitPercentage == 100 ? (null) : + let columnsHandle = !this.props.active() ? (null) : ( + <div className="collectionSchemaView-columnsHandle" onPointerDown={this.onColumnsDown} />); + let dividerDragger = this.splitPercentage == 0 ? (null) : <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} /> +<<<<<<< HEAD //get the union of all childrens' keys let addFields: { id: string, name: string }[] = []; @@ -268,6 +390,10 @@ export class CollectionSchemaView extends CollectionViewBase { } +======= + let colDividerDragger = this._columnsPercentage == 0 ? (null) : + <div className="collectionSchemaView-colDividerDragger" onPointerDown={this.onColDividerDown} style={{ height: `${this.DIVIDER_WIDTH}px` }} /> +>>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d return ( <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} > @@ -277,33 +403,53 @@ export class CollectionSchemaView extends CollectionViewBase { this._panelHeight = r.entry.height; })}> {({ measureRef }) => - <div ref={measureRef} className="collectionSchemaView-tableContainer" style={{ width: `${this._splitPercentage}%` }}> - <ReactTable - data={children} - pageSize={children.length} - page={0} - showPagination={false} - columns={columns.map(col => ({ - Header: col.Name, - accessor: (doc: Document) => [doc, col], - id: col.Id - }))} - column={{ - ...ReactTableDefaults.column, - Cell: this.renderCell, - - }} - getTrProps={this.getTrProps} - /> + <div ref={measureRef} className="collectionSchemaView-tableContainer" + style={{ width: `calc(100% - ${this.splitPercentage}%)` }}> + <div className="collectionSchemaView-reactContainer" style={{ height: `calc(100% - ${this._columnsPercentage}%)` }}> + <ReactTable + data={children} + pageSize={children.length} + page={0} + showPagination={false} + columns={columns.map(col => ({ + Header: col.Name, + accessor: (doc: Document) => [doc, col], + id: col.Id + }))} + column={{ + ...ReactTableDefaults.column, + Cell: this.renderCell, + + }} + getTrProps={this.getTrProps} + /> + </div> + {colDividerDragger} + <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} > + {/* <input type="checkbox" id="addColumn-toggle" /> + <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> */} + + <div className="addColumn-options"> + <ul style={{ overflow: "scroll" }}> + {Array.from(Object.keys(allKeys)).map(item => { + return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />) + })} + </ul> + </div> + </div> </div> } </Measure> {dividerDragger} - <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)` }}> + <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}> {content} </div> {previewHandle} +<<<<<<< HEAD {optionsMenu} +======= + {columnsHandle} +>>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d </div> </div > |
