aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx22
-rw-r--r--src/client/views/collections/collectionSchema/SchemaCellField.tsx48
-rw-r--r--src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx6
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx11
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTableCell.tsx15
5 files changed, 69 insertions, 33 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 0e5a1e6b6..11a4e88f9 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -495,6 +495,26 @@ export class CollectionSchemaView extends CollectionSubView() {
return adjIndex;
};
+ @action
+ setRelCursorIndex = (mouseY: number) => {
+ this._mouseCoordinates.y = mouseY; // updates this.rowDropIndex computed value to overwrite the old cached value
+
+ const rowHeight = CollectionSchemaView._rowHeight;
+ const adjInitMouseY = mouseY - rowHeight - 100; // rowHeight: height of the column menu cells | 100: height of the top menu
+ const yOffset = this._lowestSelectedIndex * rowHeight;
+
+ const heights = this._selectedDocs.map(() => this.rowHeightFunc());
+ let index: number = 0;
+ heights.reduce((total, curr, i) => {
+ if (total <= adjInitMouseY && total + curr >= adjInitMouseY) {
+ if (adjInitMouseY <= total + curr) index = i;
+ else index = i + 1;
+ }
+ return total + curr;
+ }, yOffset);
+ this._relCursorIndex = index;
+ };
+
highlightDraggedColumn = (index: number) =>
this._colEles.forEach((colRef, i) => {
const edgeStyle = i === index ? `solid 2px ${Colors.MEDIUM_BLUE}` : '';
@@ -731,7 +751,7 @@ export class CollectionSchemaView extends CollectionSubView() {
const field = this.columnKeys[col];
const refToAdd = `d${docIndex}.${field}`
const editedField = this._referenceSelectMode.currEditing ? this._referenceSelectMode.currEditing as SchemaCellField : null;
- editedField?.appendText(refToAdd, true);
+ editedField?.insertText(refToAdd, true);
editedField?.setupRefSelect(false);
return;
}
diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx
index 1ee79fa0b..72dcc00e6 100644
--- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx
@@ -9,6 +9,16 @@ import { ObjectField } from "../../../../fields/ObjectField";
import { Doc } from "../../../../fields/Doc";
import { DocumentView } from "../../nodes/DocumentView";
+/**
+ * The SchemaCellField renders text in schema cells while the user is editing, and updates the
+ * contents of the field based on user input. It handles some cell-side logic for equations, such
+ * as how equations are broken up within the text.
+ *
+ * The current implementation parses innerHTML to create spans based on the text in the cell.
+ * A more robust/safer approach would directly add elements in the react structure, but this
+ * has been challenging to implement.
+ */
+
export interface SchemaCellFieldProps {
contents: any;
fieldContents?: FieldViewProps;
@@ -147,20 +157,30 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
return chunkedText;
}
+ /**
+ * Sets the rendered content of the cell to save user inputs.
+ * @param content the content to set
+ * @param restoreCursorPos whether the cursor should be set back to where it was rather than the 0th index; should usually be true
+ */
@action
setContent = (content: string, restoreCursorPos?: boolean) => {
const pos = this.cursorPosition;
this._displayedContent = this.makeSpans(content);
- console.log('print', content);
restoreCursorPos && setTimeout(() => this.setCursorPosition(pos));
}
+ //Called from schemaview when a cell is selected to add a reference to the equation
+ /**
+ * Inserts text at the given index.
+ * @param text The text to append.
+ * @param atPos he index at which to insert the text. If empty, defaults to end.
+ */
@action
- appendText = (text: string, atCursorPos?: boolean) => {
+ insertText = (text: string, atPos?: boolean) => {
const content = this._unrenderedContent;
const cursorPos = this.cursorPosition;
const robustPos = cursorPos ?? content.length;
- const newText = atCursorPos ? content.slice(0, robustPos) + text + content.slice(cursorPos ?? content.length) : this._unrenderedContent.concat(text);
+ const newText = atPos ? content.slice(0, robustPos) + text + content.slice(cursorPos ?? content.length) : this._unrenderedContent.concat(text);
this.onChange(undefined, newText);
setTimeout(() => this.setCursorPosition(robustPos + text.length));
}
@@ -172,6 +192,9 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
return wasFocused !== this._editing;
};
+ /**
+ * Gets the cursor's position index within the text being edited.
+ */
get cursorPosition() {
const selection = window.getSelection();
if (!selection || selection.rangeCount === 0 || !this._inputref) return null;
@@ -185,6 +208,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
return adjRange.toString().length;
}
+
setCursorPosition = (position: number | null) => {
const selection = window.getSelection();
if (!selection || position === null || !this._inputref) return;
@@ -220,9 +244,9 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
//This function checks if a visual update (eg. coloring a cell reference) should be made. It's meant to
//save on processing upkeep vs. constantly rerendering, but I think the savings are minimal for now
- // shouldUpdate = (prevVal: string, currVal: string) => {
- // if (this._props.getCells(currVal).length !== this._props.getCells(prevVal).length) return true;
- // };
+ shouldUpdate = (prevVal: string, currVal: string) => {
+ if (this._props.getCells(currVal).length !== this._props.getCells(prevVal).length) return true;
+ };
onChange = (e: FormEvent<HTMLDivElement> | undefined, newText?: string) => {
const prevVal = this._unrenderedContent;
@@ -235,7 +259,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
}
this._unrenderedContent = targVal;
this._props.highlightCells?.(targVal);
- this.setContent(targVal, true);
+ if (this.shouldUpdate(prevVal, targVal)) this.setContent(targVal, true);
this.setupRefSelect(this.refSelectConditionMet);
};
@@ -248,10 +272,7 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.nativeEvent.defaultPrevented) return; // hack .. DashFieldView grabs native events, but react ignores stoppedPropagation and preventDefault, so we need to check it here
- // if (e.metaKey) {
- // e.stopPropagation();
- // e.preventDefault();
- // }
+
switch (e.key) {
case 'Tab':
e.stopPropagation();
@@ -295,7 +316,6 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
}
};
-
@action
onClick = (e?: React.MouseEvent) => {
if (this._props.editing !== false) {
@@ -312,6 +332,8 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
this._dependencyMessageShown = true;
return;
}
+
+ this.setContent(this._unrenderedContent);
if (this._props.SetValue(this._unrenderedContent, shiftDown, enterKey)) {
this._editing = false;
@@ -327,8 +349,6 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
}
}
- //<FieldView {...this._props.fieldContents}/>
-
staticDisplay = () => {
return <span className='editableView-static'>
{
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 6da236d82..3495c5ab4 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -5,23 +5,19 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero, setupMoveUpEvents } from '../../../../ClientUtils';
import { emptyFunction } from '../../../../Utils';
-import { Colors } from '../../global/globalEnums';
import './CollectionSchemaView.scss';
import { EditableView } from '../../EditableView';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider';
import { FieldViewProps } from '../../nodes/FieldView';
-import { Doc, Field } from '../../../../fields/Doc';
+import { Doc } from '../../../../fields/Doc';
import { dropActionType } from '../../../util/DropActionTypes';
import { Transform } from '../../../util/Transform';
import { SchemaTableCell } from './SchemaTableCell';
import { DocCast } from '../../../../fields/Types';
import { computedFn } from 'mobx-utils';
import { CollectionSchemaView } from './CollectionSchemaView';
-import { SnappingManager } from '../../../util/SnappingManager';
import { undoable } from '../../../util/UndoManager';
-import { FInfo } from '../../../documents/Documents';
-import { ColumnType } from '../../../../fields/SchemaHeaderField';
import { IconButton, Size } from 'browndash-components';
export enum SchemaFieldType {
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index ec94a8077..b928a5c67 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -25,6 +25,12 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { infoState } from '../collectionFreeForm/CollectionFreeFormInfoState';
import { TbShieldX } from 'react-icons/tb';
+/**
+ * The SchemaRowBox renders a doc as a row of cells, with each cell representing
+ * one field value of the doc. It mostly handles communication from the SchemaView
+ * to each SchemaCell, passing down necessary functions are props.
+ */
+
interface SchemaRowBoxProps extends FieldViewProps {
rowIndex: number;
}
@@ -51,10 +57,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
return this.schemaView.Document;
}
- @computed get rowIndex() {
- return this.schemaView?.rowIndex(this.Document) ?? -1;
- }
-
componentDidMount(): void {
this._props.setContentViewBox?.(this);
}
@@ -164,7 +166,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
selectReference={this.selectReference}
refSelectModeInfo={this.schemaView._referenceSelectMode}
eqHighlightFunc={this.eqHighlightFunc}
- equationHighlightRef={this.schemaView._cellHighlightColors}
highlightCells={this.highlightCells}
isolatedSelection={this.isolatedSelection}
key={key}
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index e2a05da7f..1bca3c84d 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -30,12 +30,17 @@ import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
import { FieldViewProps } from '../../nodes/FieldView';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
-import { CollectionSchemaView, FInfotoColType } from './CollectionSchemaView';
+import { FInfotoColType } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
import { SchemaColumnHeader } from './SchemaColumnHeader';
-import { ContextMenu } from '../../ContextMenu';
import { SchemaCellField } from './SchemaCellField';
+/**
+ * SchemaTableCells make up the majority of the visual representation of the SchemaView.
+ * They are rendered for each cell in the SchemaView, and each represents one field value
+ * of a doc. Editing the content of the cell changes the corresponding doc's field value.
+ */
+
export interface SchemaTableCellProps {
Document: Doc;
col: number;
@@ -62,7 +67,6 @@ export interface SchemaTableCellProps {
rowSelected: () => boolean;
isolatedSelection: (doc: Doc) => [boolean, boolean];
highlightCells: (text: string) => void;
- equationHighlightRef: ObservableMap<HTMLDivElement, string>;
eqHighlightFunc: (text: string) => HTMLDivElement[] | [];
refSelectModeInfo: {enabled: boolean, currEditing: SchemaCellField | undefined};
selectReference: (doc: Doc, col: number) => void;
@@ -143,11 +147,6 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
return { color, textDecoration, fieldProps, cursor, pointerEvents };
}
- // @action
- // appendTextToField = (text: string) => {
- // this._fieldRef?.appendText(text);
- // }
-
adjustSelfReference = (field: string) => {
const modField = field.replace(/\bthis.\b/g, `d${this.docIndex}.`);
return modField;