aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
diff options
context:
space:
mode:
authorNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2024-04-11 05:24:03 -0400
committerNathan-SR <144961007+Nathan-SR@users.noreply.github.com>2024-04-11 05:24:03 -0400
commit89e9ad0448290fe7daf6980c9c5e5cda0ce66714 (patch)
tree43c2367d2d53eb7cb128e3a3aac342e424d23a12 /src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
parentc705e22aa90710e3ba3f9ed5a6fadb0f1729f7b9 (diff)
Row dragging no longer interferes with multi-selection; dragged rows render where they will be dropped; pointerevent listeners removed from schemarowbox
Diffstat (limited to 'src/client/views/collections/collectionSchema/CollectionSchemaView.tsx')
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx104
1 files changed, 80 insertions, 24 deletions
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"