diff options
author | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2024-04-11 05:24:03 -0400 |
---|---|---|
committer | Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> | 2024-04-11 05:24:03 -0400 |
commit | 89e9ad0448290fe7daf6980c9c5e5cda0ce66714 (patch) | |
tree | 43c2367d2d53eb7cb128e3a3aac342e424d23a12 | |
parent | c705e22aa90710e3ba3f9ed5a6fadb0f1729f7b9 (diff) |
Row dragging no longer interferes with multi-selection; dragged rows render where they will be dropped; pointerevent listeners removed from schemarowbox
-rw-r--r-- | .env.swp | bin | 12349 -> 12351 bytes | |||
-rw-r--r-- | src/client/util/DocumentManager.ts | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionNoteTakingView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/collections/collectionSchema/CollectionSchemaView.tsx | 104 | ||||
-rw-r--r-- | src/client/views/collections/collectionSchema/SchemaRowBox.tsx | 41 | ||||
-rw-r--r-- | src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 5 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 1 |
7 files changed, 91 insertions, 65 deletions
Binary files differ diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index a38a330da..561114182 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -36,6 +36,7 @@ export class DocumentManager { } public DeleteDocumentView(dv: DocumentView) { this._documentViews.delete(dv); + console.log("deleted") } //private constructor so no other class can create a nodemanager @@ -94,6 +95,7 @@ export class DocumentManager { this.callAddViewFuncs(view); } // prettier-ignore }; + public RemoveView = action((view: DocumentView) => { if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) && !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) { this.DeleteDocumentView(view); @@ -125,6 +127,8 @@ export class DocumentManager { public getDocumentView(target: Doc | undefined, preferredCollection?: DocumentView): DocumentView | undefined { const docViewArray = DocumentManager.Instance.DocumentViews; + //console.log(docViewArray) + //console.log(this._documentViews) const passes = !target ? [] : preferredCollection ? [preferredCollection, undefined] : [undefined]; return passes.reduce( (toReturn, pass) => diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index 6318620e0..8c10db5dc 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -138,6 +138,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { sections.get(existingHeader)!.push(d); } }); + //*!* // now we add back in the docs that we're dragging if (rowCol.length && columnHeaders.length > rowCol[1]) { const offset = 0; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index f59d562dd..050f303c2 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -3,7 +3,7 @@ import { Popup, PopupTrigger, Type } from 'browndash-components'; import { ObservableMap, action, computed, makeObservable, observable, observe } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils'; +import { StopEvent, emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils'; import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; @@ -91,7 +91,8 @@ export class CollectionSchemaView extends CollectionSubView() { //an array of selected docs and the index representing the selected column @observable _selectedCol: number = 0; @observable _selectedCells: Array<Doc> | undefined; - + @observable _mouseY: number = 0; + @observable _mouseX: number = 0; // target HTMLelement portal for showing a popup menu to edit cell values. public get MenuTarget() { @@ -99,7 +100,11 @@ export class CollectionSchemaView extends CollectionSubView() { } @computed get _selectedDocs() { - const selected = SelectionManager.Docs.filter(doc => Doc.AreProtosEqual(DocCast(doc.embedContainer), this.Document)); + // get all selected documents then filter out any whose parent is not this schema document + const selected = SelectionManager.Docs.filter(doc => this.childDocs.includes(doc)); + // SelectionManager... filter(doc => this.childDocs.includes(doc)) + //DocCast(doc.embedContainer)[DocData] === this.dataDoc + //SelectionManager.Docs.forEach(doc => console.log("index: " + this.rowIndex(doc) + " equal: " + Doc.AreProtosEqual(DocCast(doc.embedContainer), this.Document))); if (!selected.length) { for (const sel of SelectionManager.Docs) { const contextPath = DocumentManager.GetContextPath(sel, true); @@ -128,6 +133,10 @@ export class CollectionSchemaView extends CollectionSubView() { return Cast(this.layoutDoc.schema_columnKeys, listSpec('string'), defaultColumnKeys); } + @computed get rowKeys() { + return Cast(this.layoutDoc.schema_rowKeys, listSpec('string'), []); + } + @computed get storedColumnWidths() { const widths = NumListCast( this.layoutDoc.schema_columnWidths, @@ -135,12 +144,18 @@ export class CollectionSchemaView extends CollectionSubView() { ); const totalWidth = widths.reduce((sum, width) => sum + width, 0); + //If the total width of all columns is not the width of the schema table minus the width of the row menu, resize them appropriately if (totalWidth !== this.tableWidth - CollectionSchemaView._rowMenuWidth) { return widths.map(w => (w / totalWidth) * (this.tableWidth - CollectionSchemaView._rowMenuWidth)); } return widths; } + @computed get rowHeights() { + const heights = this.childDocs.map(() => (this.rowHeightFunc())) + return heights; + } + @computed get displayColumnWidths() { return this._displayColumnWidths ?? this.storedColumnWidths; } @@ -211,11 +226,11 @@ export class CollectionSchemaView extends CollectionSubView() { break; case 'ArrowUp': { - const firstDoc = this._selectedDocs.lastElement(); - const firstIndex = this.rowIndex(firstDoc); + const firstIndex = this.lastSelectedIndex; const curDoc = this.sortedDocs.docs[firstIndex]; if (firstIndex > 0 && firstIndex < this.childDocs.length) { - const newDoc = this.sortedDocs.docs[firstIndex - 1]; + console.log("firstindex: " + firstIndex + " docs: " + this.childDocs.length) + const newDoc = firstIndex < this.childDocs.length - 1 ? this.sortedDocs.docs[firstIndex - 1] : curDoc; if (this._selectedDocs.includes(newDoc)){ SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(curDoc)) this.deselectCell(curDoc); @@ -255,6 +270,15 @@ export class CollectionSchemaView extends CollectionSubView() { } }; + @computed get lastSelectedIndex() { + let lastIndex: number = 0; + if (this._selectedCells) for (let i = 0; i < this._selectedCells?.length; ++i){ + let rowIndex = this.rowIndex(this._selectedCells[i]); + (rowIndex > lastIndex) && (lastIndex = rowIndex); + } + return lastIndex; + } + @action changeSelectedCellColumn = () => { @@ -390,6 +414,19 @@ export class CollectionSchemaView extends CollectionSubView() { } return total + curr; }, CollectionSchemaView._rowMenuWidth); + console.log(index); + return index; + }; + + findRowDropIndex = (mouseY: number) => { + let index: number = 0; + this.rowHeights.reduce((total, curr, i) => { + if (total <= mouseY && total + curr >= mouseY) { + if (mouseY <= total + curr) index = i; + else index = i + 1; + } + return total + curr; + }, CollectionSchemaView._rowHeight); return index; }; @@ -428,6 +465,7 @@ export class CollectionSchemaView extends CollectionSubView() { addDocToSelection = (doc: Doc, extendSelection: boolean, index: number) => { const rowDocView = DocumentManager.Instance.getDocumentView(doc); if (rowDocView) SelectionManager.SelectView(rowDocView, extendSelection); + else console.log("nonexistent") }; @action @@ -443,29 +481,31 @@ export class CollectionSchemaView extends CollectionSubView() { const endRow = Math.max(lastSelectedRow, index); for (let i = startRow; i <= endRow; i++) { const currDoc = this.sortedDocs.docs[i]; - if (!this._selectedDocs.includes(currDoc)) this.addDocToSelection(currDoc, true, i); - this._selectedCells && this._selectedCells.push(currDoc); + if (!this._selectedDocs.includes(currDoc)){ + this.selectCell(currDoc, this._selectedCol, false, true) + } } }; @action - selectCell = (doc: Doc, index: number, shiftKey: boolean, ctrlKey: boolean) => { - (!shiftKey && !ctrlKey) && this.clearSelection(); + selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { + if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); - this._selectedCells.push(doc); + !shiftKey && this._selectedCells && this._selectedCells.push(doc); if (!this) return; const lastSelected = Array.from(this._selectedDocs).lastElement(); if (shiftKey && lastSelected && !this._selectedDocs.includes(doc)) this.selectRows(doc, lastSelected); - else if (ctrlKey && lastSelected && this._selectedDocs.includes(doc)) { - console.log("removed"); - SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(doc)) - this.deselectCell(doc); + else if (ctrlKey) { + if (lastSelected && this._selectedDocs.includes(doc)){ + SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(doc)) + this.deselectCell(doc); + } else this.addDocToSelection(doc, true, this.rowIndex(doc)); } - else if (ctrlKey) {this.addDocToSelection(doc, true, this.rowIndex(doc)); console.log("2")} else this.addDocToSelection(doc, false, this.rowIndex(doc)); + this._selectedCol = col; - this._selectedCol = index; + //let selectedIndexes: Array<Number> = this._selectedCells.map(doc => this.rowIndex(doc)); }; @action @@ -480,7 +520,12 @@ export class CollectionSchemaView extends CollectionSubView() { sortedSelectedDocs = () => this.sortedDocs.docs.filter(doc => this._selectedDocs.includes(doc)); - setDropIndex = (index: number) => (this._closestDropIndex = index); + @computed + get rowDropIndex(){ + const mouseY = this.ScreenToLocalBoxXf().transformPoint(this._mouseX, this._mouseY)[1]; + const index = this.findRowDropIndex(mouseY); + return index + } onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.columnDragData) { @@ -502,14 +547,14 @@ export class CollectionSchemaView extends CollectionSubView() { } const draggedDocs = de.complete.docDragData?.draggedDocuments; if (draggedDocs && super.onInternalDrop(e, de) && !this.sortField) { - const pushedDocs = this.childDocs.filter((doc, index) => index >= this._closestDropIndex && !draggedDocs.includes(doc)); + const pushedDocs = this.childDocs.filter((doc, index) => index >= this.rowDropIndex && !draggedDocs.includes(doc)); const pushedAndDraggedDocs = [...pushedDocs, ...draggedDocs]; const removed = this.childDocs.slice().filter(doc => !pushedAndDraggedDocs.includes(doc)); this.dataDoc[this.fieldKey ?? 'data'] = new List<Doc>([...removed, ...draggedDocs, ...pushedDocs]); this.clearSelection(); draggedDocs.forEach(doc => { const draggedView = DocumentManager.Instance.getFirstDocumentView(doc); - if (draggedView) DocumentManager.Instance.RemoveView(draggedView); + //if (draggedView) DocumentManager.Instance.RemoveView(draggedView); //this is what messed up multi-select with row dragging DocumentManager.Instance.AddViewRenderedCb(doc, dv => dv.select(true)); }); return true; @@ -880,12 +925,21 @@ export class CollectionSchemaView extends CollectionSubView() { ); } + @action + onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => { + if (DragManager.docsBeingDragged.length){ + this._mouseY = e.clientY; + this._mouseX = e.clientX; + } + } + @computed get sortedDocs() { const field = StrCast(this.layoutDoc.sortField); - const desc = BoolCast(this.layoutDoc.sortDesc); + const desc = BoolCast(this.layoutDoc.sortDesc); // is this an ascending or descending sort + const staticDocs = this.childDocs.filter(d => !DragManager.docsBeingDragged.includes(d)); const docs = !field - ? this.childDocs - : [...this.childDocs].sort((docA, docB) => { + ? staticDocs + : [...staticDocs].sort((docA, docB) => { // this sorts the documents based on the selected field. returning -1 for a before b, 0 for a = b, 1 for a > b const aStr = Field.toString(docA[field] as Field); const bStr = Field.toString(docB[field] as Field); var out = 0; @@ -894,8 +948,10 @@ export class CollectionSchemaView extends CollectionSubView() { if (desc) out *= -1; return out; }); + docs.splice(this.rowDropIndex, 0, ...DragManager.docsBeingDragged) return { docs }; } + rowHeightFunc = () => (BoolCast(this.layoutDoc._schema_singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight); sortedDocsFunc = () => this.sortedDocs; isContentActive = () => this._props.isSelected() || this._props.isContentActive(); @@ -905,7 +961,7 @@ export class CollectionSchemaView extends CollectionSubView() { _oldWheel: any; render() { return ( - <div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)}> + <div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)} onPointerMove={(e) => this.onPointerMove(e)}> <div ref={this._menuTarget} style={{ background: 'red', top: 0, left: 0, position: 'absolute', zIndex: 10000 }}></div> <div className="schema-table" diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 33b2d36d6..4fd2894af 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -5,7 +5,7 @@ import { computedFn } from 'mobx-utils'; import * as React from 'react'; import { CgClose, CgLock, CgLockUnlock } from 'react-icons/cg'; import { FaExternalLinkAlt } from 'react-icons/fa'; -import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils'; +import { StopEvent, emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils'; import { Doc } from '../../../../fields/Doc'; import { BoolCast } from '../../../../fields/Types'; import { DragManager } from '../../../util/DragManager'; @@ -63,46 +63,11 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { } }; - onPointerEnter = (e: any) => { - if (SnappingManager.IsDragging && this._props.isContentActive()) { - document.removeEventListener('pointermove', this.onPointerMove); - document.addEventListener('pointermove', this.onPointerMove); - } - }; - - onPointerMove = (e: any) => { - const dragIsRow = DragManager.docsBeingDragged.some(doc => doc.embedContainer === this.schemaDoc); // this.schemaView?._selectedDocs.has(doc) ?? false; - - 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.schemaView?.setDropIndex(this.rowIndex); - } else if (y > halfLine) { - this._ref.style.borderTop = '0px'; - this._ref.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`; - this.schemaView?.setDropIndex(this.rowIndex + 1); - } - } - }; - - onPointerLeave = (e: any) => { - if (this._ref) { - this._ref.style.borderTop = '0px'; - this._ref.style.borderBottom = '0px'; - } - document.removeEventListener('pointermove', this.onPointerMove); - }; - selectedCol = () => this.schemaView._selectedCol; getFinfo = computedFn((fieldKey: string) => this.schemaView?.fieldInfos.get(fieldKey)); selectCell = (doc: Doc, col: number, shift: boolean, ctrl: boolean) => this.schemaView?.selectCell(doc, col, shift, ctrl); deselectCell = () => this.schemaView?.deselectAllCells(); - selectedCells = () => this.schemaView?._selectedCells; + selectedCells = () => this.schemaView?._selectedDocs; setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false; setSelectedColumnValues = (field: any, value: any) => this.schemaView?.setSelectedColumnValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); @@ -111,8 +76,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { <div className="schema-row" style={{ height: this._props.PanelHeight(), backgroundColor: this._props.isSelected() ? Colors.LIGHT_BLUE : undefined }} - onPointerEnter={this.onPointerEnter} - onPointerLeave={this.onPointerLeave} ref={(row: HTMLDivElement | null) => { row && this.schemaView?.addRowRef?.(this.Document, row); this._ref = row; diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 6a75ad6c5..1786d688b 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -7,7 +7,7 @@ import * as React from 'react'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; import Select from 'react-select'; -import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero } from '../../../../Utils'; +import { StopEvent, Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero } from '../../../../Utils'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field } from '../../../../fields/Doc'; import { RichTextField } from '../../../../fields/RichTextField'; @@ -110,7 +110,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro @computed get selected() { const selected: Doc[] | undefined = this._props.selectedCells(); - let istrue = this._props.isRowActive() && (selected && selected?.filter(doc => doc === this._props.Document).length !== 0) && this._props.selectedCol() === this._props.col; + let istrue = this._props.isRowActive() && (selected?.filter(doc => doc === this._props.Document).length !== 0) && this._props.selectedCol() === this._props.col; return istrue; } @@ -182,6 +182,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro return ( <div className="schema-table-cell" + onContextMenu={e => StopEvent(e)} onPointerDown={action(e => { const shift: boolean = e.shiftKey; const ctrl: boolean = e.ctrlKey; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 8d3750cad..3764f6edd 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -279,6 +279,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document } startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) { + //console.log("docview drag") const docView = this._docView; if (this._mainCont.current && docView) { const views = SelectionManager.Views.filter(dv => dv.ContentDiv); |