diff options
Diffstat (limited to 'src/client/views/collections/collectionSchema/SchemaRowBox.tsx')
-rw-r--r-- | src/client/views/collections/collectionSchema/SchemaRowBox.tsx | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx new file mode 100644 index 000000000..661056553 --- /dev/null +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -0,0 +1,123 @@ +import React = require('react'); +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { action, ObservableMap, ObservableSet } from 'mobx'; +import { observer } from 'mobx-react'; +import { Doc } from '../../../../fields/Doc'; +import { undoBatch } from '../../../util/UndoManager'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { Colors } from '../../global/globalEnums'; +import { FieldView, FieldViewProps } from '../../nodes/FieldView'; +import './CollectionSchemaView.scss'; +import { SchemaTableCell } from './SchemaTableCell'; +import { emptyFunction, setupMoveUpEvents } from '../../../../Utils'; +import { DragManager } from '../../../util/DragManager'; + +export interface SchemaRowBoxProps extends FieldViewProps { + rowIndex: number; + columnKeys: string[]; + columnWidths: number[]; + rowMenuWidth: number; + selectedRows: ObservableSet<Doc>; + selectRow: (e: any, doc: Doc, index: number) => void; + startDrag: (e: any, doc: Doc) => boolean; + dragging: boolean; + dropIndex: (index: number) => void; +} + +@observer +export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(SchemaRowBox, fieldKey); + } + + private _ref: HTMLDivElement | null = null; + + isSelected = () => this.props.selectedRows.has(this.props.Document); + bounds = () => this._ref?.getBoundingClientRect(); + + @action + onRowPointerDown = (e: React.PointerEvent) => { + e.stopPropagation(); + + setupMoveUpEvents( + this, + e, + e => this.props.startDrag(e, this.props.Document), + emptyFunction, + e => this.props.selectRow(e, this.props.Document, this.props.rowIndex) + ); + }; + + onPointerEnter = (e: any) => { + if (!this.props.dragging) return; + document.removeEventListener('pointermove', this.onPointerMove); + document.addEventListener('pointermove', this.onPointerMove); + }; + + onPointerMove = (e: any) => { + if (!this.props.dragging) return; + let dragIsRow: boolean = true; + DragManager.docsBeingDragged.forEach(doc => { + dragIsRow = this.props.selectedRows.has(doc); + }); + if (this._ref && dragIsRow) { + const rect = this._ref.getBoundingClientRect(); + const y = e.clientY - rect.top; //y position within the element. + const height = this._ref.clientHeight; + const halfLine = height / 2; + if (y <= halfLine) { + this._ref.style.borderTop = `solid 2px ${Colors.MEDIUM_BLUE}`; + this._ref.style.borderBottom = '0px'; + this.props.dropIndex(this.props.rowIndex); + } else if (y > halfLine) { + this._ref.style.borderTop = '0px'; + this._ref.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`; + this.props.dropIndex(this.props.rowIndex + 1); + } + } + }; + + onPointerLeave = (e: any) => { + if (this._ref) { + this._ref.style.borderTop = '0px'; + this._ref.style.borderBottom = '0px'; + } + document.removeEventListener('pointermove', this.onPointerMove); + }; + + render() { + return ( + <div + className="schema-row" + style={this.isSelected() ? { backgroundColor: Colors.LIGHT_BLUE, opacity: this.props.dragging ? 0.5 : 1 } : {}} + onPointerDown={this.onRowPointerDown} + onPointerEnter={this.onPointerEnter} + onPointerLeave={this.onPointerLeave} + ref={(row: HTMLDivElement | null) => (this._ref = row)}> + <div className="row-menu" style={{ width: this.props.rowMenuWidth }}> + <div + className="row-button" + onPointerDown={undoBatch(e => { + e.stopPropagation(); + this.props.removeDocument?.(this.props.Document); + })}> + <FontAwesomeIcon icon="times" /> + </div> + <div + className="row-button" + onPointerDown={e => { + e.stopPropagation(); + this.props.addDocTab(this.props.Document, 'add:right'); + }}> + <FontAwesomeIcon icon="external-link-alt" /> + </div> + </div> + <div className="row-cells"> + {this.props.columnKeys.map((key, index) => ( + <SchemaTableCell Document={this.props.Document} fieldKey={key} columnWidth={this.props.columnWidths[index]} /> + ))} + </div> + </div> + ); + } +} |