From 0766ba00727e9e13ced2e16cfb049d49711fa738 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 8 May 2024 23:50:29 -0400 Subject: schema cell tag functions written --- .../collections/collectionSchema/SchemaTableCell.tsx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index b017eb62b..8192c5e2a 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -184,20 +184,24 @@ export class SchemaTableCell extends ObservableReactComponent) => { + if (this._props.isRowActive?.() !== false) { + if (this.selected && ctrl) { + this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); + e.stopPropagation(); + } else !this.selected && this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); + } + } + render() { return (
StopEvent(e)} onPointerDown={action(e => { - const shift: boolean = e.shiftKey; - const ctrl: boolean = e.ctrlKey; - if (this._props.isRowActive?.() !== false) { - if (this.selected && ctrl) { - this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); - e.stopPropagation(); - } else !this.selected && this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); - } + + this.select(e.shiftKey, e.ctrlKey, e); + })} style={{ padding: this._props.padding, maxWidth: this._props.maxWidth?.(), width: this._props.columnWidth() || undefined, border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> {this.content} -- cgit v1.2.3-70-g09d2 From d6e449b84e1b35cf434b49f0476aa7242cc6c03b Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 9 May 2024 00:06:12 -0400 Subject: fixed merge --- .../collectionSchema/SchemaTableCell.tsx | 86 +++++++++------------- 1 file changed, 35 insertions(+), 51 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index c1677b024..67991b8a2 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -25,9 +25,9 @@ import { Transform } from '../../../util/Transform'; import { undoBatch, undoable } from '../../../util/UndoManager'; import { EditableView } from '../../EditableView'; import { ObservableReactComponent } from '../../ObservableReactComponent'; -import { DefaultStyleProvider } from '../../StyleProvider'; +import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider'; import { Colors } from '../../global/globalEnums'; -import { DocFocusOrOpen, returnEmptyDocViewList } from '../../nodes/DocumentView'; +import { DocumentView } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { FInfotoColType } from './CollectionSchemaView'; @@ -59,6 +59,14 @@ export interface SchemaTableCellProps { rootSelected?: () => boolean; } +function selectedCell(props: SchemaTableCellProps) { + return ( + props.isRowActive() && + props.selectedCol() === props.col && // + props.selectedCells()?.filter(d => d === props.Document)?.length + ); +} + @observer export class SchemaTableCell extends ObservableReactComponent { constructor(props: SchemaTableCellProps) { @@ -67,7 +75,7 @@ export class SchemaTableCell extends ObservableReactComponent { - DocFocusOrOpen(toList(docs)[0]); + DocumentView.FocusOrOpen(toList(docs)[0]); return true; }; public static renderProps(props: SchemaTableCellProps) { @@ -114,11 +122,6 @@ export class SchemaTableCell extends ObservableReactComponent doc === this._props.Document).length !== 0 && this._props.selectedCol() === this._props.col; - } - @computed get defaultCellContent() { const { color, textDecoration, fieldProps, pointerEvents } = SchemaTableCell.renderProps(this._props); @@ -132,12 +135,12 @@ export class SchemaTableCell extends ObservableReactComponent this.selected && this._props.autoFocus && r?.setIsFocused(true)} + ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} contents={undefined} fieldContents={fieldProps} - editing={this.selected ? undefined : false} + editing={selectedCell(this._props) ? undefined : false} GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { @@ -157,39 +160,27 @@ export class SchemaTableCell extends ObservableReactComponent; - case ColumnType.Boolean: return ; - case ColumnType.RTF: return ; + switch (this.getCellType) { + case ColumnType.Image: return ; + case ColumnType.Boolean: return ; + case ColumnType.RTF: return ; case ColumnType.Enumeration: return Field.toString(val))} />; - case ColumnType.Date: return ; - default: return this.defaultCellContent; - } - } - - select = (shift: boolean, ctrl: boolean, e: React.MouseEvent) => { - if (this._props.isRowActive?.() !== false) { - if (this.selected && ctrl) { - this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); - e.stopPropagation(); - } else !this.selected && this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); + case ColumnType.Date: return ; + default: return this.defaultCellContent; } } @@ -199,9 +190,16 @@ export class SchemaTableCell extends ObservableReactComponent StopEvent(e)} onPointerDown={action(e => { - this.select(e.shiftKey, e.ctrlKey, e); + const shift: boolean = e.shiftKey; + const ctrl: boolean = e.ctrlKey; + if (this._props.isRowActive?.() !== false) { + if (selectedCell(this._props) && ctrl) { + this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); + e.stopPropagation(); + } else !selectedCell(this._props) && this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); + } })} - style={{ padding: this._props.padding, maxWidth: this._props.maxWidth?.(), width: this._props.columnWidth() || undefined, border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> + style={{ padding: this._props.padding, maxWidth: this._props.maxWidth?.(), width: this._props.columnWidth() || undefined, border: selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> {this.content}
); @@ -331,20 +329,14 @@ export class SchemaRTFCell extends ObservableReactComponent doc === this._props.Document).length !== 0 && this._props.selectedCol() === this._props.col; - // return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col; - } - // if the text box blurs and none of its contents are focused(), then the edit finishes - selectedFunc = () => this.selected; + selectedFunc = () => !!selectedCell(this._props); render() { const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props); fieldProps.isContentActive = this.selectedFunc; return ( -
- {this.selected ? this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))} +
+ {selectedCell(this._props) ? this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
); } @@ -356,10 +348,6 @@ export class SchemaBoolCell extends ObservableReactComponent doc === this._props.Document).length !== 0 && this._props.selectedCol() === this._props.col; - } render() { const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props); return ( @@ -377,7 +365,7 @@ export class SchemaBoolCell extends ObservableReactComponent Field.toKeyValueString(this._props.Document, this._props.fieldKey)} SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { @@ -401,10 +389,6 @@ export class SchemaEnumerationCell extends ObservableReactComponent doc === this._props.Document).length !== 0 && this._props.selectedCol() === this._props.col; - } render() { const { color, textDecoration, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props); const options = this._props.options?.map(facet => ({ value: facet, label: facet })); @@ -457,4 +441,4 @@ export class SchemaEnumerationCell extends ObservableReactComponent ); } -} +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 2d7037dd5664700cda04b1fb0c6c77fe6f49d66c Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 9 May 2024 23:33:17 -0400 Subject: goodbye old parser ;( hello new parser :) --- src/client/documents/Documents.ts | 2 +- src/client/views/FieldsDropdown.tsx | 4 +- .../collectionSchema/CollectionSchemaView.tsx | 75 +++++++++++----------- .../collections/collectionSchema/SchemaRowBox.tsx | 2 + .../collectionSchema/SchemaTableCell.tsx | 6 +- 5 files changed, 48 insertions(+), 41 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1c18c0d84..f0974f5dd 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -43,7 +43,7 @@ export class FInfo { readOnly: boolean = false; fieldType?: FInfoFieldType; values?: FieldType[]; - + onLayout?: boolean; filterable?: boolean = true; // can be used as a Filter in FilterPanel // format?: string; // format to display values (e.g, decimal places, $, etc) // parse?: ScriptField; // parse a value from a string diff --git a/src/client/views/FieldsDropdown.tsx b/src/client/views/FieldsDropdown.tsx index 0ea0ebd83..011cd51b3 100644 --- a/src/client/views/FieldsDropdown.tsx +++ b/src/client/views/FieldsDropdown.tsx @@ -34,7 +34,7 @@ export class FieldsDropdown extends ObservableReactComponent(); SearchUtil.foreachRecursiveDoc([this._props.Document], (depth, doc) => allDocs.add(doc)); return Array.from(allDocs); @@ -57,7 +57,7 @@ export class FieldsDropdown extends ObservableReactComponent facet[0] === facet.charAt(0).toUpperCase())]; Object.entries(DocOptions) - .filter(opts => opts[1].filterable) + .filter(opts => opts[1].filterable) //!!! .forEach((pair: [string, FInfo]) => filteredOptions.push(pair[0])); const options = filteredOptions.sort().map(facet => ({ value: facet, label: facet })); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 19d170c81..e493b2e5d 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; -import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, FieldType, IdToDoc, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; @@ -288,7 +288,6 @@ export class CollectionSchemaView extends CollectionSubView() { this.addNewKey(key, defaultVal); } - this.modifyCellTags(true); const newColWidth = this.tableWidth / (this.storedColumnWidths.length + 1); const currWidths = this.storedColumnWidths.slice(); currWidths.splice(0, 0, newColWidth); @@ -302,19 +301,24 @@ export class CollectionSchemaView extends CollectionSubView() { @action addNewKey = (key: string, defaultVal: any) => { - if (this._newFieldType == ColumnType.Equation) { - this.childDocs.forEach(doc => { - const parsedEquation = this.parseEquation(defaultVal); - const val = computed(() => { return this.parsedEquationResult(parsedEquation, doc);}) - doc[DocData][key] = val.get(); - // doc[DocData][key] = this.parsedEquationResult(eq, doc); - // this.setupAutoUpdate(eq, doc); - }); - } else { - this.childDocs.forEach(doc => { - doc[DocData][key] = defaultVal; - }); + this.childDocs.forEach(doc => { + doc[DocData][key] = defaultVal; + }); + } + + cleanupComputedField = (field: string) => { + const idPattern = /idToDoc\((.*?)\)/g; + let modField = field.slice(); + let matches; + let results = new Map(); + while ((matches = idPattern.exec(field)) !== null) { + results.set(matches[0], matches[1].replace(/"/g, '')); } + console.log(results); + results.forEach((id, funcId) => { + modField = modField.replace(funcId, 'd' + (this.rowIndex(IdToDoc(id)) + 1).toString()); + }) + return modField; } // @action @@ -325,30 +329,30 @@ export class CollectionSchemaView extends CollectionSubView() { // }); // } - parseEquation = (eq: string): [string, Map] => { - const variablePattern = /[a-z]+/gi; - const tagRefPattern = /{([^}]*)}/g; - const docTagRefPairs = new Map(); - let modifiedEq = eq; - let match; + // parseEquation = (eq: string): [string, Map] => { + // const variablePattern = /[a-z]+/gi; + // const tagRefPattern = /{([^}]*)}/g; + // const docTagRefPairs = new Map(); + // let modifiedEq = eq; + // let match; - while (match = tagRefPattern.exec(eq)) { - const ref = match[1]; - const [doc, key] = this.getCellInfoFromTag(ref); - docTagRefPairs.set(ref, doc); - const replacement = `docTagRefPairs.get('${ref}').${key}`; - modifiedEq = modifiedEq.replace(new RegExp(`{${ref}}`, 'g'), replacement); - } + // while (match = tagRefPattern.exec(eq)) { + // const ref = match[1]; + // const [doc, key] = this.getCellInfoFromTag(ref); + // docTagRefPairs.set(ref, doc); + // const replacement = `docTagRefPairs.get('${ref}').${key}`; + // modifiedEq = modifiedEq.replace(new RegExp(`{${ref}}`, 'g'), replacement); + // } - //modifiedEq = modifiedEq.replace(variablePattern, (match) => `doc.${match}`); + // modifiedEq = modifiedEq.replace(variablePattern, (match) => `doc.${match}`); - return [modifiedEq, docTagRefPairs]; - } + // return [modifiedEq, docTagRefPairs]; + // } - parsedEquationResult = (eq: [string, Map], doc: any): number => { - const func = new Function('doc', 'docTagRefPairs', 'return ' + eq[0]); - return func(doc, eq[1]); - } + // parsedEquationResult = (eq: [string, Map], doc: any): number => { + // const func = new Function('doc', 'docTagRefPairs', 'return ' + eq[0]); + // return func(doc, eq[1]); + // } @undoBatch removeColumn = (index: number) => { @@ -547,7 +551,6 @@ export class CollectionSchemaView extends CollectionSubView() { selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { this.populateCellTags(); console.log(this.getCellTag(doc, col)); - console.log(this.getCellInfoFromTag("C1")); if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); !shiftKey && this._selectedCells && this._selectedCells.push(doc); @@ -602,7 +605,7 @@ export class CollectionSchemaView extends CollectionSubView() { const colTag = tag.replace(/[^A-Z]/g, ''); const col = lettersToNumber(colTag); - const key: string = this.columnKeys[col]; + const key: string = this.columnKeys[col - 1]; const rowNum = Number(tag.replace(/[^\d]/g, '')); const doc = this.childDocs[rowNum - 1]; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 760089ffb..3295c9ab1 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -52,6 +52,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { this._props.setContentViewBox?.(this); } + cleanupField = (field: string) => this.schemaView.cleanupComputedField(field) setCursorIndex = (mouseY: number) => this.schemaView?.setRelCursorIndex(mouseY); selectedCol = () => this.schemaView._selectedCol; getFinfo = computedFn((fieldKey: string) => this.schemaView?.fieldInfos.get(fieldKey)); @@ -149,6 +150,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { setSelectedColumnValues={this.setSelectedColumnValues} oneLine={BoolCast(this.schemaDoc?._singleLine)} menuTarget={this.schemaView.MenuTarget} + cleanupField={this.cleanupField} transform={() => { const ind = index === this.schemaView.columnKeys.length - 1 ? this.schemaView.columnKeys.length - 3 : index; const x = this.schemaView?.displayColumnWidths.reduce((p, c, i) => (i <= ind ? p + c : p), 0); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 67991b8a2..d11af6b3c 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -57,6 +57,7 @@ export interface SchemaTableCellProps { transform: () => Transform; autoFocus?: boolean; // whether to set focus on creation, othwerise wait for a click rootSelected?: () => boolean; + cleanupField: (field: string) => string; } function selectedCell(props: SchemaTableCellProps) { @@ -141,14 +142,15 @@ export class SchemaTableCell extends ObservableReactComponent Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)} + GetValue={() => this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} //TODO: feed this into parser that handles idToDoc SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); this._props.finishEdit?.(); return true; } - const ret = Doc.SetField(fieldProps.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(fieldProps.Document) ? true : undefined); + const hasNoLayout = Doc.IsDataProto(fieldProps.Document) ? true : undefined; // the "delegate" is a a data document so never write to it's proto + const ret = Doc.SetField(fieldProps.Document, this._props.fieldKey.replace(/^_/, ''), value, hasNoLayout); this._props.finishEdit?.(); return ret; }, 'edit schema cell')} -- cgit v1.2.3-70-g09d2 From 3b5cecea920b62a5d1633d8c6603b3b152794611 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 13 May 2024 00:54:49 -0400 Subject: editable column header started --- src/client/documents/Documents.ts | 1 + .../collectionSchema/CollectionSchemaView.tsx | 3 +- .../collectionSchema/SchemaColumnHeader.tsx | 90 ++++++++++++++++++++-- .../collectionSchema/SchemaTableCell.tsx | 2 +- 4 files changed, 88 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f0974f5dd..3cc0d5604 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -87,6 +87,7 @@ class DocInfo extends FInfo { constructor(d: string, filterable?: boolean, values?: Doc[]) { super(d, true); this.values = values; + console.log(this.values); this.filterable = filterable; } override searchable = () => false; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index e493b2e5d..c9d5307c9 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -312,9 +312,8 @@ export class CollectionSchemaView extends CollectionSubView() { let matches; let results = new Map(); while ((matches = idPattern.exec(field)) !== null) { - results.set(matches[0], matches[1].replace(/"/g, '')); + results.set(matches[0], matches[1]); } - console.log(results); results.forEach((id, funcId) => { modField = modField.replace(funcId, 'd' + (this.rowIndex(IdToDoc(id)) + 1).toString()); }) diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 6b5a34ec0..dad0c214b 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -1,14 +1,20 @@ /* eslint-disable react/no-unused-prop-types */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action } from 'mobx'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { setupMoveUpEvents } from '../../../../ClientUtils'; +import { returnEmptyDoclist, returnEmptyFilter, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { Colors } from '../../global/globalEnums'; import './CollectionSchemaView.scss'; +import { EditableView } from '../../EditableView'; +import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider'; +import { FieldViewProps } from '../../nodes/FieldView'; export interface SchemaColumnHeaderProps { + autoFocus?: boolean; + oneLine?: boolean; // whether all input should fit on one line vs allowing textare multiline inputs + allowCRs?: boolean; // allow carriage returns in text input (othewrise CR ends the edit) columnKeys: string[]; columnWidths: number[]; columnIndex: number; @@ -26,6 +32,9 @@ export interface SchemaColumnHeaderProps { @observer export class SchemaColumnHeader extends React.Component { + + @observable _editing: boolean = false; + get fieldKey() { return this.props.columnKeys[this.props.columnIndex]; } @@ -44,10 +53,81 @@ export class SchemaColumnHeader extends React.Component }; @action - onPointerDown = (e: React.PointerEvent) => { + setupDrag = (e: React.PointerEvent) => { this.props.isContentActive(true) && setupMoveUpEvents(this, e, moveEv => this.props.dragColumn(moveEv, this.props.columnIndex), emptyFunction, emptyFunction); }; + public static renderProps(props: SchemaColumnHeaderProps) { + const { Document, fieldKey, getFinfo, columnWidth, isContentActive } = props; + let protoCount = 0; + let doc: Doc | undefined = Document; + while (doc) { + if (Object.keys(doc).includes(fieldKey.replace(/^_/, ''))) { + break; + } + protoCount++; + doc = DocCast(doc.proto); + } + const parenCount = Math.max(0, protoCount - 1); + const color = protoCount === 0 || (fieldKey.startsWith('_') && Document[fieldKey] === undefined) ? 'black' : 'blue'; // color of text in cells + const textDecoration = color !== 'black' && parenCount ? 'underline' : ''; + const fieldProps: FieldViewProps = { + childFilters: returnEmptyFilter, + childFiltersByRanges: returnEmptyFilter, + docViewPath: returnEmptyDocViewList, + searchFilterDocs: returnEmptyDoclist, + styleProvider: DefaultStyleProvider, + isSelected: returnFalse, + setHeight: returnFalse, + select: emptyFunction, + dragAction: dropActionType.move, + renderDepth: 1, + noSidebar: true, + isContentActive: returnFalse, + whenChildContentsActiveChanged: emptyFunction, + ScreenToLocalTransform: Transform.Identity, + focus: emptyFunction, + addDocTab: SchemaTableCell.addFieldDoc, + pinToPres: returnZero, + Document: DocCast(Document.rootDocument, Document), + fieldKey: fieldKey, + PanelWidth: columnWidth, + PanelHeight: props.rowHeight, + rootSelected: props.rootSelected, + }; + const readOnly = getFinfo(fieldKey)?.readOnly ?? false; + const cursor = !readOnly ? 'text' : 'default'; + const pointerEvents = 'all'; + return { color, textDecoration, fieldProps, cursor, pointerEvents }; + } + + @computed get editableView() { + const { color, textDecoration, fieldProps, pointerEvents } = SchemaColumnHeader.renderProps(this.props); + + return this.props.autoFocus && r?.setIsFocused(true)} + oneLine={this.props.oneLine} + allowCRs={this.props.allowCRs} + contents={undefined} + fieldContents={fieldProps} + editing={this._editing ? undefined : false} + GetValue={() => this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)).replace(/[";]/g, '')} //TODO: feed this into parser that handles idToDoc + SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { + if (shiftDown && enterKey) { + this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); + this._props.finishEdit?.(); + return true; + } + const hasNoLayout = Doc.IsDataProto(fieldProps.Document) ? true : undefined; // the "delegate" is a a data document so never write to it's proto + const ret = Doc.SetField(fieldProps.Document, this._props.fieldKey.replace(/^_/, ''), value, hasNoLayout); + this._props.finishEdit?.(); + return ret; + }, 'edit schema cell')} + /> + } + render() { return (
style={{ width: this.props.columnWidths[this.props.columnIndex], }} - onPointerDown={this.onPointerDown} + onPointerDown={this.setupDrag} ref={col => { if (col) { this.props.setColRef(this.props.columnIndex, col); } }}>
this.props.resizeColumn(e, this.props.columnIndex)} /> -
{this.fieldKey}
+
{this._editing = true; console.log(this._editing)}}>{this.fieldKey}
this.props.openContextMenu(e.clientX, e.clientY, this.props.columnIndex)}> diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index d11af6b3c..733cf3722 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -142,7 +142,7 @@ export class SchemaTableCell extends ObservableReactComponent this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} //TODO: feed this into parser that handles idToDoc + GetValue={() => this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)).replace(/[";]/g, '')} //TODO: feed this into parser that handles idToDoc SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); -- cgit v1.2.3-70-g09d2 From b27056fc67c654dea72338f928cd69026a501c0f Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 14 May 2024 15:58:23 -0400 Subject: editable columnheader progress; still not updating properly on adding new col --- src/client/views/EditableView.tsx | 10 ++++-- .../collectionSchema/CollectionSchemaView.scss | 12 +++++++ .../collectionSchema/CollectionSchemaView.tsx | 39 ++-------------------- .../collectionSchema/SchemaColumnHeader.tsx | 34 ++++++++++++------- .../collectionSchema/SchemaTableCell.tsx | 2 +- 5 files changed, 45 insertions(+), 52 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 05c926399..1eec11e64 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -54,6 +54,8 @@ export interface EditableProps { background?: string | undefined; placeholder?: string; wrap?: string; // nowrap, pre-wrap, etc + + isColHeader?: boolean; } /** @@ -135,7 +137,9 @@ export class EditableView extends ObservableReactComponent { if (!e.currentTarget.value) this._props.OnEmpty?.(); break; case 'Enter': + console.log("enter press detected") if (this._props.allowCRs !== true) { + console.log("noCrs??") e.stopPropagation(); if (!e.ctrlKey) { this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, true); @@ -242,9 +246,9 @@ export class EditableView extends ObservableReactComponent { /> ) : this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? ( { this._inputref = r; }} // prettier-ignore - style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background }} + style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background}} placeholder={this._props.placeholder} onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)} defaultValue={this._props.GetValue()} @@ -277,7 +281,7 @@ export class EditableView extends ObservableReactComponent { render() { const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); - if (this._editing && gval !== undefined) { + if ((this._editing && gval !== undefined) || this._props.isColHeader) { return this._props.sizeToContent ? (
{gval}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 6fb8e40db..269bb4de5 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -162,6 +162,13 @@ min-width: 20%; } + .schema-column-edit-wrapper { + flex-grow: 2; + margin: 5px; + overflow: hidden; + min-width: 20%; + } + .schema-header-menu { margin: 5px; } @@ -176,6 +183,11 @@ } } + .editableView-input { + border: none; + outline: none; + } + /*.schema-column-resizer.left { min-width: 5px; transform: translate(-3px, 0px); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index d74cb56cf..2d181a772 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -277,6 +277,7 @@ export class CollectionSchemaView extends CollectionSubView() { this.addNewKey(newKey, defaultVal); console.log("added") } + console.log("changed " + index) const currKeys = this.columnKeys.slice(); // copy the column key array first, then change it. currKeys[index] = newKey; @@ -321,39 +322,6 @@ export class CollectionSchemaView extends CollectionSubView() { return modField; } - // @action - // setupAutoUpdate = (equation: string, doc: Doc) => { - // return autorun(() => { - // const result = this.parsedEquationResult(equation, doc); - // doc[DocData][equation] = result; - // }); - // } - - // parseEquation = (eq: string): [string, Map] => { - // const variablePattern = /[a-z]+/gi; - // const tagRefPattern = /{([^}]*)}/g; - // const docTagRefPairs = new Map(); - // let modifiedEq = eq; - // let match; - - // while (match = tagRefPattern.exec(eq)) { - // const ref = match[1]; - // const [doc, key] = this.getCellInfoFromTag(ref); - // docTagRefPairs.set(ref, doc); - // const replacement = `docTagRefPairs.get('${ref}').${key}`; - // modifiedEq = modifiedEq.replace(new RegExp(`{${ref}}`, 'g'), replacement); - // } - - // modifiedEq = modifiedEq.replace(variablePattern, (match) => `doc.${match}`); - - // return [modifiedEq, docTagRefPairs]; - // } - - // parsedEquationResult = (eq: [string, Map], doc: any): number => { - // const func = new Function('doc', 'docTagRefPairs', 'return ' + eq[0]); - // return func(doc, eq[1]); - // } - @undoBatch removeColumn = (index: number) => { if (this.columnKeys.length === 1) return; @@ -745,14 +713,13 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - setKey = (key: string, defaultVal?: any) => { + setKey = (key: string, defaultVal?: any, index?: number) => { console.log("setKey called with" + key) if (this._makeNewColumn) { this.addColumn(key, defaultVal); this._makeNewColumn = false; } else { - this.changeColumnKey(this._columnMenuIndex!, key, defaultVal); - console.log("changed") + this.changeColumnKey(this._columnMenuIndex! | index!, key, defaultVal); } this.closeColumnMenu(); }; diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index b74b2ace9..794d5d8ac 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -53,12 +53,12 @@ export class SchemaColumnHeader extends ObservableReactComponent this._props.schemaView?.fieldInfos.get(fieldKey)); - setColumnValues = (field: string, defaultValue: string) => {this._props.schemaView?.setKey(field, defaultValue);} + setColumnValues = (field: string, defaultValue: string) => {this._props.schemaView?.setKey(field, defaultValue, this._props.columnIndex);} @action sortClicked = (e: React.PointerEvent) => { @@ -108,24 +108,34 @@ export class SchemaColumnHeader extends ObservableReactComponent + return
this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} contents={undefined} fieldContents={fieldProps} - editing={this._editing ? undefined : false} - GetValue={() => Field.toKeyValueString(fieldProps.Document, this.fieldKey, SnappingManager.MetaKey).replace(/[";]/g, '')} - SetValue={undoable((value: string) => { - this.setColumnValues(value, value); + editing={undefined} + isColHeader={true} + GetValue={() => {console.log(this.fieldKey); return this.fieldKey}} + SetValue={undoable((value: string, shiftKey?: boolean, enterKey?: boolean) => { + if (shiftKey && enterKey) { + this.setColumnValues(value, value); + this._props.finishEdit?.(); + return true; + } this._props.finishEdit?.(); return true; }, 'edit column header')} @@ -133,9 +143,9 @@ export class SchemaColumnHeader extends ObservableReactComponent } - staticView = () => { - return
{this._editing = true; console.log(this._editing)}}>{this.fieldKey}
- } + // staticView = () => { + // return
{this._editing = true; console.log(this._editing)}}>{this.fieldKey}
+ // } render() { return ( @@ -152,7 +162,7 @@ export class SchemaColumnHeader extends ObservableReactComponent
this._props.resizeColumn(e, this._props.columnIndex)} /> -
{this._editing ? this.editableView : this.staticView()}
+
{this.editableView}
this._props.openContextMenu(e.clientX, e.clientY, this._props.columnIndex)}> diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 733cf3722..51a92ff35 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -194,7 +194,7 @@ export class SchemaTableCell extends ObservableReactComponent { const shift: boolean = e.shiftKey; const ctrl: boolean = e.ctrlKey; - if (this._props.isRowActive?.() !== false) { + if (this._props.isRowActive?.()) { if (selectedCell(this._props) && ctrl) { this._props.selectCell(this._props.Document, this._props.col, shift, ctrl); e.stopPropagation(); -- cgit v1.2.3-70-g09d2 From 5b6e6b27a191a880fd454ebbc5ed3816cd5cd59c Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:23:38 -0400 Subject: new columns display blank --- src/client/views/EditableView.tsx | 2 + .../collectionSchema/CollectionSchemaView.scss | 10 +++-- .../collectionSchema/CollectionSchemaView.tsx | 48 ++++++---------------- .../collectionSchema/SchemaColumnHeader.tsx | 34 ++++++++------- .../collectionSchema/SchemaTableCell.tsx | 4 +- 5 files changed, 43 insertions(+), 55 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 4c4ef227a..5b691c507 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -56,6 +56,7 @@ export interface EditableProps { wrap?: string; // nowrap, pre-wrap, etc showKeyNotVal?: boolean; + updateAlt?: (newAlt: string) => void; } /** @@ -182,6 +183,7 @@ export class EditableView extends ObservableReactComponent { @action onClick = (e: React.MouseEvent) => { + if (this._props.GetValue() == 'None' && this._props.updateAlt) this._props.updateAlt('.'); if (this._props.editing !== false) { e.nativeEvent.stopPropagation(); if (this._ref.current && this._props.showMenuOnLoad) { diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index fd2e882d9..1dbe75a8d 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -50,13 +50,15 @@ .schema-column-menu, .schema-filter-menu { background: $light-gray; - position: relative; - min-width: 200px; - max-width: 400px; + position: absolute; + min-width: 150px; + max-width: 300px; + max-height: 300px; display: flex; + overflow: hidden; flex-direction: column; align-items: flex-start; - z-index: 1; + z-index: 5; .schema-key-search-input { width: calc(100% - 20px); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index db23f874e..c673f0e56 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -32,6 +32,7 @@ import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; import { ActionButton } from '@adobe/react-spectrum'; +import { CollectionMasonryViewFieldRow } from '../CollectionMasonryViewFieldRow'; const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore @@ -273,9 +274,7 @@ export class CollectionSchemaView extends CollectionSubView() { @undoBatch changeColumnKey = (index: number, newKey: string, defaultVal?: any) => { - if (!this.documentKeys.includes(newKey)) { - this.addNewKey(newKey, defaultVal); - } + if (!this.documentKeys.includes(newKey)) this.addNewKey(newKey, defaultVal); const currKeys = this.columnKeys.slice(); // copy the column key array first, then change it. currKeys[index] = newKey; @@ -283,10 +282,8 @@ export class CollectionSchemaView extends CollectionSubView() { }; @undoBatch - addColumn = (key: string, defaultVal?: any) => { - if (!this.documentKeys.includes(key)) { - this.addNewKey(key, defaultVal); - } + addColumn = (key?: string, defaultVal?: any) => { + if (key && !this.documentKeys.includes(key)) this.addNewKey(key, defaultVal); const newColWidth = this.tableWidth / (this.storedColumnWidths.length + 1); const currWidths = this.storedColumnWidths.slice(); @@ -295,7 +292,9 @@ export class CollectionSchemaView extends CollectionSubView() { this.layoutDoc.schema_columnWidths = new List(currWidths.map(w => (w / newDesiredTableWidth) * (this.tableWidth - CollectionSchemaView._rowMenuWidth))); const currKeys = this.columnKeys.slice(); + if (!key) key = 'EmptyColumnKey' + Math.floor(Math.random() * 1000000000000000).toString(); currKeys.splice(0, 0, key); + this.changeColumnKey(0, 'EmptyColumnKey' + Math.floor(Math.random() * 1000000000000000).toString()); this.layoutDoc.schema_columnKeys = new List(currKeys); }; @@ -332,6 +331,7 @@ export class CollectionSchemaView extends CollectionSubView() { const currKeys = this.columnKeys.slice(); currKeys.splice(index, 1); this.layoutDoc.schema_columnKeys = new List(currKeys); + console.log(...currKeys); }; @action @@ -784,29 +784,13 @@ export class CollectionSchemaView extends CollectionSubView() { this._filterColumnIndex = undefined; }; - openContextMenu = (x: number, y: number, index: number, fieldType: ColumnType) => { + openContextMenu = (x: number, y: number, index: number) => { this.closeColumnMenu(); this.closeFilterMenu(); - let toDisplay: string = ''; - switch (fieldType) { - case ColumnType.Number: - toDisplay = 'number'; - break; - case ColumnType.String: - toDisplay = 'string'; - break; - case ColumnType.Boolean: - toDisplay = 'boolean'; - break; - default: - toDisplay = 'string'; - break; - } - ContextMenu.Instance.clearItems(); ContextMenu.Instance.addItem({ - description: `Field type: ${toDisplay}`, + description: `Change field`, event: () => this.openColumnMenu(index, false), icon: 'pencil-alt', }); @@ -923,14 +907,6 @@ export class CollectionSchemaView extends CollectionSubView() { onClick={() => this.toggleMenuKeyFilter()}> {this._colKeysFiltered ? "All keys" : "Active keys only"} -
{ - e.stopPropagation(); - this._makeNewField = true; - })}> - + new field -
{ @@ -1077,7 +1053,9 @@ export class CollectionSchemaView extends CollectionSubView() { _oldWheel: any; render() { return ( -
this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)} onPointerMove={e => this.onPointerMove(e)}> +
this.createDashEventsTarget(ele)} + onDrop={this.onExternalDrop.bind(this)} + onPointerMove={e => this.onPointerMove(e)} >
this.openColumnMenu(-1, true)} icon="plus" />} + toggle={ this.addColumn()} icon="plus" />} //here trigger={PopupTrigger.CLICK} type={Type.TERT} isOpen={this._columnMenuIndex !== -1 ? false : undefined} diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index f404eb444..6e2f85cc0 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -39,7 +39,7 @@ export interface SchemaColumnHeaderProps { rowHeight: () => number; resizeColumn: (e: any, index: number) => void; dragColumn: (e: any, index: number) => boolean; - openContextMenu: (x: number, y: number, index: number, fieldType: ColumnType) => void; + openContextMenu: (x: number, y: number, index: number) => void; setColRef: (index: number, ref: HTMLDivElement) => void; rootSelected?: () => boolean; columnWidth: () => number; @@ -50,15 +50,21 @@ export interface SchemaColumnHeaderProps { @observer export class SchemaColumnHeader extends ObservableReactComponent { - @observable _editing: boolean | undefined = false; - @observable _fieldType: ColumnType = ColumnType.String; + @observable _altTitle: string | undefined = undefined; @computed get fieldKey() { return this._props.columnKeys[this._props.columnIndex]; } + isDefaultTitle = (key: string) => { + const defaultPattern = /EmptyColumnKey/; + let isDefault: boolean = (defaultPattern.exec(key) != null); + return isDefault; + } + getFinfo = computedFn((fieldKey: string) => this._props.schemaView?.fieldInfos.get(fieldKey)); setColumnValues = (field: string, defaultValue: string) => {this._props.schemaView?.setKey(field, defaultValue, this._props.columnIndex);} + @action updateAlt = (newAlt: string) => {this._altTitle = newAlt;} @action sortClicked = (e: React.PointerEvent) => { @@ -128,15 +134,21 @@ export class SchemaColumnHeader extends ObservableReactComponent this.fieldKey} + GetValue={() => { + if (this.isDefaultTitle(this.fieldKey)) return ''; + else if (this._altTitle) return this._altTitle; + else return this.fieldKey; + }} SetValue={undoable((value: string, shiftKey?: boolean, enterKey?: boolean) => { if (shiftKey && enterKey) { // if shift & enter, set value of each cell in column - this.setColumnValues(value, value); + this.setColumnValues(value, ''); + this._altTitle = undefined; this._props.finishEdit?.(); return true; - } - this._props.finishEdit?.(); // else save new value to header field + } else if (enterKey) this.updateAlt(value); + this._props.finishEdit?.(); return true; }, 'edit column header')} /> @@ -155,12 +167,6 @@ export class SchemaColumnHeader extends ObservableReactComponent { - // console.log(true); - // this._editing = true}} - // onPointerLeave={() => { - // console.log(false); - // this._editing = false}} ref={col => { if (col) { this._props.setColRef(this._props.columnIndex, col); @@ -171,7 +177,7 @@ export class SchemaColumnHeader extends ObservableReactComponent{this.editableView}
-
this._props.openContextMenu(e.clientX, e.clientY, this._props.columnIndex, this._fieldType)}> +
this._props.openContextMenu(e.clientX, e.clientY, this._props.columnIndex)}>
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 51a92ff35..4531f30a8 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -142,7 +142,7 @@ export class SchemaTableCell extends ObservableReactComponent this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)).replace(/[";]/g, '')} //TODO: feed this into parser that handles idToDoc + GetValue={() => this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} //TODO: feed this into parser that handles idToDoc SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); @@ -150,7 +150,7 @@ export class SchemaTableCell extends ObservableReactComponent Date: Mon, 3 Jun 2024 13:33:25 -0400 Subject: merge prep --- .../collectionSchema/CollectionSchemaView.tsx | 34 +++++----------------- .../collections/collectionSchema/SchemaRowBox.tsx | 2 -- .../collectionSchema/SchemaTableCell.tsx | 1 - src/client/views/global/globalScripts.ts | 2 ++ 4 files changed, 10 insertions(+), 29 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index c673f0e56..ef1819120 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -700,42 +700,24 @@ export class CollectionSchemaView extends CollectionSubView() { @action setKey = (key: string, defaultVal?: any, index?: number) => { - if (this.columnKeys.includes(key)){ - return; - } - + if (this.columnKeys.includes(key)) return; + if (this._makeNewColumn) { this.addColumn(key, defaultVal); this._makeNewColumn = false; - } else { - this.changeColumnKey(this._columnMenuIndex! | index!, key, defaultVal); - } + } else this.changeColumnKey(this._columnMenuIndex! | index!, key, defaultVal); + this.closeColumnMenu(); }; setCellValues = (key: string, value: string) => { const selectedDocs: Doc[] = []; this.childDocs.forEach(doc => { - const docIsSelected = this._selectedCells && !(this._selectedCells?.filter(d => d === doc).length === 0); - if (docIsSelected) { - selectedDocs.push(doc); - } - }); - if (selectedDocs.length === 1) { - this.childDocs.forEach(doc => Doc.SetField(doc, key, value)); - } else { - selectedDocs.forEach(doc => Doc.SetField(doc, key, value)); - } - return true; - }; - - setSelectedColumnValues = (key: string, value: string) => { - this.childDocs.forEach(doc => { - const docIsSelected = this._selectedCells && !(this._selectedCells?.filter(d => d === doc).length === 0); - if (docIsSelected) { - Doc.SetField(doc, key, value); - } + const isSelected = this._selectedCells && !(this._selectedCells?.filter(d => d === doc).length === 0); + isSelected && selectedDocs.push(doc); }); + if (selectedDocs.length === 1) this.childDocs.forEach(doc => Doc.SetField(doc, key, value)); // if only one cell selected, fill all + else selectedDocs.forEach(doc => Doc.SetField(doc, key, value)); // else only fill selected cells return true; }; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 908939ecc..da272cd18 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -60,7 +60,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { deselectCell = () => this.schemaView?.deselectAllCells(); selectedCells = () => this.schemaView?._selectedDocs; setColumnValues = (field: any, value: any) => this.schemaView?.setCellValues(field, value) ?? false; - setSelectedColumnValues = (field: any, value: any) => this.schemaView?.setSelectedColumnValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); render() { return ( @@ -147,7 +146,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { selectedCells={this.selectedCells} selectedCol={this.selectedCol} setColumnValues={this.setColumnValues} - setSelectedColumnValues={this.setSelectedColumnValues} oneLine={BoolCast(this.schemaDoc?._singleLine)} menuTarget={this.schemaView.MenuTarget} cleanupField={this.cleanupField} diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 4531f30a8..e6660f379 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -48,7 +48,6 @@ export interface SchemaTableCellProps { isRowActive: () => boolean | undefined; getFinfo: (fieldKey: string) => FInfo | undefined; setColumnValues: (field: string, value: string) => boolean; - setSelectedColumnValues: (field: string, value: string) => boolean; oneLine?: boolean; // whether all input should fit on one line vs allowing textare multiline inputs allowCRs?: boolean; // allow carriage returns in text input (othewrise CR ends the edit) finishEdit?: () => void; // notify container that edit is over (eg. to hide view in DashFieldView) diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index c595681b7..8e5c39ddf 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -66,6 +66,8 @@ ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: b } else { const dataKey = Doc.LayoutFieldKey(dv.Document); const alternate = (dv.layoutDoc[dataKey + '_usePath'] ? '_' + dv.layoutDoc[dataKey + '_usePath'] : '').replace(':hover', ''); + console.log('color: ' + dv.dataDoc[fieldKey + alternate] + ' to set to: ' + color) + dv.layoutDoc[fieldKey + alternate] = undefined; dv.dataDoc[fieldKey + alternate] = color; } }); -- cgit v1.2.3-70-g09d2 From d215534d6f0d66db9d5bf15f9fefef3fe5398024 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:01:47 -0400 Subject: c --- .../collectionSchema/CollectionSchemaView.scss | 5 ++ .../collectionSchema/CollectionSchemaView.tsx | 9 +-- .../collectionSchema/SchemaColumnHeader.tsx | 66 ++++++++++++---------- .../collectionSchema/SchemaTableCell.tsx | 4 +- 4 files changed, 45 insertions(+), 39 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 1dbe75a8d..3d89a479a 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -301,3 +301,8 @@ width: 12px; } } + +.header-dropdown-container { + height: 0px; + width: 60px; +} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index ef1819120..92cc58f54 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -33,6 +33,7 @@ import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; import { ActionButton } from '@adobe/react-spectrum'; import { CollectionMasonryViewFieldRow } from '../CollectionMasonryViewFieldRow'; +import { Func } from 'mocha'; const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore @@ -706,7 +707,7 @@ export class CollectionSchemaView extends CollectionSubView() { this.addColumn(key, defaultVal); this._makeNewColumn = false; } else this.changeColumnKey(this._columnMenuIndex! | index!, key, defaultVal); - + this.closeColumnMenu(); }; @@ -884,11 +885,6 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get keysDropdown() { return (
-
{ @@ -1065,6 +1061,7 @@ export class CollectionSchemaView extends CollectionSubView() { CollectionSchemaView._minColWidth} //TODO: update Document={this.Document} diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 6e2f85cc0..4f9d53d18 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -32,6 +32,7 @@ export interface SchemaColumnHeaderProps { sortField: string; sortDesc: boolean; schemaView: CollectionSchemaView; + keysDropdown: React.JSX.Element; //cleanupField: (s: string) => string; isContentActive: (outsideReaction?: boolean | undefined) => boolean | undefined; setSort: (field: string | undefined, desc?: boolean) => void; @@ -51,17 +52,12 @@ export interface SchemaColumnHeaderProps { export class SchemaColumnHeader extends ObservableReactComponent { @observable _altTitle: string | undefined = undefined; + @observable _displayKeysDropdown: boolean = false; @computed get fieldKey() { return this._props.columnKeys[this._props.columnIndex]; } - - isDefaultTitle = (key: string) => { - const defaultPattern = /EmptyColumnKey/; - let isDefault: boolean = (defaultPattern.exec(key) != null); - return isDefault; - } - + getFinfo = computedFn((fieldKey: string) => this._props.schemaView?.fieldInfos.get(fieldKey)); setColumnValues = (field: string, defaultValue: string) => {this._props.schemaView?.setKey(field, defaultValue, this._props.columnIndex);} @action updateAlt = (newAlt: string) => {this._altTitle = newAlt;} @@ -79,6 +75,11 @@ export class SchemaColumnHeader extends ObservableReactComponent { + this._props.schemaView.openColumnMenu(this._props.columnIndex, false) + this._displayKeysDropdown = true; + } + @action setupDrag = (e: React.PointerEvent) => { this._props.isContentActive(true) && setupMoveUpEvents(this, e, moveEv => this._props.dragColumn(moveEv, this._props.columnIndex), emptyFunction, emptyFunction); @@ -121,7 +122,7 @@ export class SchemaColumnHeader extends ObservableReactComponent this._props.schemaView.openColumnMenu(this._props.columnIndex, false)} style={{ color, width: '100%', @@ -148,6 +149,7 @@ export class SchemaColumnHeader extends ObservableReactComponent } - // staticView = () => { - // return
{this._editing = true; console.log(this._editing)}}>{this.fieldKey}
- // } + isDefaultTitle = (key: string) => { + const defaultPattern = /EmptyColumnKey/; + let isDefault: boolean = (defaultPattern.exec(key) != null); + return isDefault; + } render() { return ( -
{ - if (col) { - this._props.setColRef(this._props.columnIndex, col); - } - }}> -
this._props.resizeColumn(e, this._props.columnIndex)} /> +
{ + if (col) { + this._props.setColRef(this._props.columnIndex, col); + } + }}> +
this._props.resizeColumn(e, this._props.columnIndex)} /> -
{this.editableView}
+
{this.editableView}
-
-
this._props.openContextMenu(e.clientX, e.clientY, this._props.columnIndex)}> - -
-
- +
+
this._props.openContextMenu(e.clientX, e.clientY, this._props.columnIndex)}> + +
+
+ +
-
); } } diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index e6660f379..c3a58b505 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -30,7 +30,7 @@ import { Colors } from '../../global/globalEnums'; import { DocumentView } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; -import { FInfotoColType } from './CollectionSchemaView'; +import { CollectionSchemaView, FInfotoColType } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; export interface SchemaTableCellProps { @@ -149,7 +149,7 @@ export class SchemaTableCell extends ObservableReactComponent Date: Fri, 7 Jun 2024 02:36:18 -0400 Subject: lots of UI improvements --- src/client/views/EditableView.tsx | 16 +++++++------ .../collectionSchema/CollectionSchemaView.scss | 4 ---- .../collectionSchema/CollectionSchemaView.tsx | 2 ++ .../collectionSchema/SchemaColumnHeader.tsx | 19 ++++++++------- .../collections/collectionSchema/SchemaRowBox.tsx | 3 ++- .../collectionSchema/SchemaTableCell.tsx | 27 ++++++++++++++++++---- 6 files changed, 46 insertions(+), 25 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index c79cabd6a..5b690bf33 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -55,7 +55,7 @@ export interface EditableProps { placeholder?: string; wrap?: string; // nowrap, pre-wrap, etc - showKeyNotVal?: boolean; + schemaHeader?: boolean; updateAlt?: (newAlt: string) => void; updateSearch?: (value: string) => void; } @@ -77,6 +77,7 @@ export class EditableView extends ObservableReactComponent { super(props); makeObservable(this); this._editing = !!this._props.editing; + if (this._props.schemaHeader) this._editing = true; } componentDidMount(): void { @@ -184,9 +185,9 @@ export class EditableView extends ObservableReactComponent { }; @action - onClick = (e: React.MouseEvent) => { + onClick = (e?: React.MouseEvent) => { if (this._props.editing !== false) { - e.nativeEvent.stopPropagation(); + e?.nativeEvent.stopPropagation(); if (this._ref.current && this._props.showMenuOnLoad) { this._props.menuCallback?.(this._ref.current.getBoundingClientRect().x, this._ref.current.getBoundingClientRect().y); } else { @@ -280,12 +281,13 @@ export class EditableView extends ObservableReactComponent { ); } - display = () => { + staticDisplay = () => { let toDisplay; const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); - if (this._props.showKeyNotVal){ + if (this._props.schemaHeader){ toDisplay = { fontSize: this._props.fontSize, }} onClick={this.onClick}> - {this.display()} + {this.staticDisplay()}
); } diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 3d89a479a..ceffc7e44 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -302,7 +302,3 @@ } } -.header-dropdown-container { - height: 0px; - width: 60px; -} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 39bde7d37..ec1341b14 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -758,6 +758,8 @@ const filteredChildDocs = sortedDocs.filter((doc: Doc) => !this._lentDocs. @action openColumnMenu = (index: number, newCol: boolean) => { + this.closeFilterMenu(); + this._makeNewColumn = false; this._columnMenuIndex = index; this._menuValue = ''; diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 03cf64fc8..bda9fc9b7 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -57,6 +57,11 @@ export class SchemaColumnHeader extends ObservableReactComponent this._props.schemaView?.fieldInfos.get(fieldKey)); setColumnValues = (field: string, defaultValue: string) => {this._props.schemaView?.setKey(field, defaultValue, this._props.columnIndex);} @@ -77,10 +82,7 @@ export class SchemaColumnHeader extends ObservableReactComponent { - if (this.isDefaultTitle(this.fieldKey)){ - this._props.schemaView.openColumnMenu(this._props.columnIndex, false) - this._displayKeysDropdown = true; - } + this._props.schemaView.openColumnMenu(this._props.columnIndex, false) } @action @@ -125,7 +127,7 @@ export class SchemaColumnHeader extends ObservableReactComponent this.openKeyDropdown()} + return
{SchemaColumnHeader.isDefaultField(this.fieldKey) && this.openKeyDropdown()}} style={{ color, width: '100%', @@ -138,11 +140,12 @@ export class SchemaColumnHeader extends ObservableReactComponent { - if (this.isDefaultTitle(this.fieldKey)) return ''; + if (SchemaColumnHeader.isDefaultField(this.fieldKey)) return ''; else if (this._altTitle) return this._altTitle; else return this.fieldKey; }} @@ -160,7 +163,7 @@ export class SchemaColumnHeader extends ObservableReactComponent } - isDefaultTitle = (key: string) => { + public static isDefaultField = (key: string) => { const defaultPattern = /EmptyColumnKey/; let isDefault: boolean = (defaultPattern.exec(key) != null); return isDefault; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 8ac2c0314..8cac302ce 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -113,7 +113,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { }}> } + icon={ } size={Size.XSMALL} onPointerDown={e => setupMoveUpEvents( @@ -133,6 +133,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { {this.schemaView?.columnKeys?.map((key, index) => ( boolean; cleanupField: (field: string) => string; + rowSelected: () => boolean; } function selectedCell(props: SchemaTableCellProps) { return ( props.isRowActive() && - props.selectedCol() === props.col && // + props.selectedCol() === props.col && props.selectedCells()?.filter(d => d === props.Document)?.length ); } @@ -74,6 +76,10 @@ export class SchemaTableCell extends ObservableReactComponent { DocumentView.FocusOrOpen(toList(docs)[0]); return true; @@ -89,9 +95,8 @@ export class SchemaTableCell extends ObservableReactComponent - {this.content} + style={{ padding: this._props.padding, + maxWidth: this._props.maxWidth?.(), + width: this._props.columnWidth() || undefined, + border: selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined, + backgroundColor: this.backgroundColor}}> + {this.defaultKey ? '' : this.content}
); } -- cgit v1.2.3-70-g09d2 From 4b604b5118a1aac89d977c832c81495ec2c9aa19 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:56:51 -0400 Subject: lock row editing --- src/client/documents/Documents.ts | 1 + src/client/views/EditableView.tsx | 2 ++ .../collectionSchema/CollectionSchemaView.tsx | 11 ++------ .../collectionSchema/SchemaColumnHeader.tsx | 1 + .../collections/collectionSchema/SchemaRowBox.tsx | 15 ++++++++-- .../collectionSchema/SchemaTableCell.tsx | 33 ++++++++++++---------- 6 files changed, 37 insertions(+), 26 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4908d2952..dabbf9591 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -228,6 +228,7 @@ export class DocumentOptions { _lockedPosition?: BOOLt = new BoolInfo("lock the x,y coordinates of the document so that it can't be dragged"); _lockedTransform?: BOOLt = new BoolInfo('lock the freeform_panx,freeform_pany and scale parameters of the document so that it be panned/zoomed'); _childrenSharedWithSchema?: BOOLt = new BoolInfo("whether this document's children are displayed in its parent schema view", false); + _lockedSchemaEditing?: BOOLt = new BoolInfo("", false); dataViz_title?: string; dataViz_line?: string; diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 1652e6cd7..c05812e1a 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -57,6 +57,7 @@ export interface EditableProps { wrap?: string; // nowrap, pre-wrap, etc schemaHeader?: boolean; + onClick?: () => void; updateAlt?: (newAlt: string) => void; updateSearch?: (value: string) => void; } @@ -187,6 +188,7 @@ export class EditableView extends ObservableReactComponent { @action onClick = (e?: React.MouseEvent) => { + this._props.onClick && this._props.onClick(); if (this._props.editing !== false) { e?.nativeEvent.stopPropagation(); if (this._ref.current && this._props.showMenuOnLoad) { diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 7302a7c22..48287c3ec 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -208,7 +208,7 @@ export class CollectionSchemaView extends CollectionSubView() { removeDoc = (doc: Doc) => { this.removeDocument(doc); - this._docs = this._docs.filter(d => d !== doc); + this._docs = this._docs.filter(d => d !== doc) } rowIndex = (doc: Doc) => this.displayedDocs.docs.indexOf(doc); @@ -739,13 +739,8 @@ export class CollectionSchemaView extends CollectionSubView() { }; setCellValues = (key: string, value: string) => { - const selectedDocs: Doc[] = []; - this.childDocs.forEach(doc => { - const isSelected = this._selectedCells && !(this._selectedCells?.filter(d => d === doc).length === 0); - isSelected && selectedDocs.push(doc); - }); - if (selectedDocs.length === 1) this.childDocs.forEach(doc => Doc.SetField(doc, key, value)); // if only one cell selected, fill all - else selectedDocs.forEach(doc => Doc.SetField(doc, key, value)); // else only fill selected cells + if (this._selectedCells.length === 1) this.childDocs.forEach(doc => !doc._lockedSchemaEditing && Doc.SetField(doc, key, value)); // if only one cell selected, fill all + else this._selectedCells.forEach(doc => !doc._lockedSchemaEditing && Doc.SetField(doc, key, value)); // else only fill selected cells return true; }; diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index dbbf76ea7..3719840ff 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -126,6 +126,7 @@ export class SchemaColumnHeader extends ObservableReactComponent() { icon: 'minus', }); ContextMenu.Instance.addItem({ - description: this.Document._lockedPosition ? 'Unlock doc interactions' : 'Lock doc interactions', - event: () => Doc.toggleLockedPosition(this.Document), - icon: this.Document._lockedPosition ? 'lock-open' : 'lock', + description: this.Document._lockedSchemaEditing ? 'Unlock field editing' : 'Lock field editing', + event: () => this.Document._lockedSchemaEditing = !this.Document._lockedSchemaEditing, + icon: this.Document._lockedSchemaEditing ? 'lock-open' : 'lock', }); ContextMenu.Instance.addItem({ description: 'Open preview', @@ -87,6 +87,14 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { ContextMenu.Instance.displayMenu(x, y, undefined, false); } + get menuBackgroundColor(){ + if (this.Document._lockedSchemaEditing){ + if (this._props.isSelected()) return '#B0D1E7' + else return '#F5F5F5' + } + return '' + } + cleanupField = (field: string) => this.schemaView.cleanupComputedField(field) setCursorIndex = (mouseY: number) => this.schemaView?.setRelCursorIndex(mouseY); selectedCol = () => this.schemaView._selectedCol; @@ -111,6 +119,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { style={{ width: CollectionSchemaView._rowMenuWidth, pointerEvents: !this._props.isContentActive() ? 'none' : undefined, + backgroundColor: this.menuBackgroundColor }}> { @@ -89,9 +101,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} @@ -190,14 +201,6 @@ export class SchemaTableCell extends ObservableReactComponent - {this.defaultKey ? '' : this.content} + {this.isDefault ? '' : this.content}
); } -- cgit v1.2.3-70-g09d2 From 74849a5f9307ca64e2bbafa9eaa77822de18102d Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 10 Jun 2024 20:41:14 -0400 Subject: bug fixed --- .../views/collections/collectionSchema/CollectionSchemaView.tsx | 5 +++-- src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 1952f59f5..dc29e7413 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -105,7 +105,7 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get _selectedDocs() { // get all selected documents then filter out any whose parent is not this schema document - const selected = DocumentView.SelectedDocs().filter(doc => this._docs.includes(doc)); + const selected = DocumentView.SelectedDocs().filter(doc => this.docs.includes(doc)); if (!selected.length) { // if no schema doc is directly selected, test if a child of a schema doc is selected (such as in the preview window) const childOfSchemaDoc = DocumentView.SelectedDocs().find(sel => DocumentView.getContextPath(sel, true).includes(this.Document)); @@ -525,7 +525,8 @@ export class CollectionSchemaView extends CollectionSubView() { selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); - !shiftKey && this._selectedCells && this._selectedCells.push(doc); + !shiftKey && this._selectedCells.push(doc); + this._selectedCells.forEach(d => console.log(d.title)) const index = this.rowIndex(doc); if (!this) return; diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 49ec70b74..791465741 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -215,6 +215,7 @@ export class SchemaTableCell extends ObservableReactComponent Date: Wed, 12 Jun 2024 02:50:19 -0400 Subject: fixed col drag highlight and cleaned up multi-select highlight --- .../collectionSchema/CollectionSchemaView.tsx | 14 +------- .../collections/collectionSchema/SchemaRowBox.tsx | 23 ++++++++---- .../collectionSchema/SchemaTableCell.tsx | 42 +++++++++++++++++++--- 3 files changed, 54 insertions(+), 25 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 033bc74d2..25a1b4819 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -325,17 +325,6 @@ export class CollectionSchemaView extends CollectionSubView() { }); } - // parses a field from the "idToDoc(####)" format to DocumentId (d#) format for readability - cleanupComputedField = (field: string) => { - const idPattern = /idToDoc\((.*?)\)/g; - let modField = field.slice(); - let matches; - let results = new Map(); - while ((matches = idPattern.exec(field)) !== null) {results.set(matches[0], matches[1].replace(/"/g, '')); } - results.forEach((id, funcId) => {modField = modField.replace(funcId, 'd' + (DocumentView.getDocViewIndex(IdToDoc(id))).toString());}) - return modField; - } - @undoBatch removeColumn = (index: number) => { if (this.columnKeys.length === 1) return; @@ -480,7 +469,7 @@ export class CollectionSchemaView extends CollectionSubView() { const edgeStyle = i === index ? `solid 2px ${Colors.MEDIUM_BLUE}` : ''; const cellEles = [ colRef, - ...this.childDocs + ...this.docs .filter(doc => i !== this._selectedCol || !this._selectedDocs.includes(doc)) .map(doc => this._rowEles.get(doc).children[1].children[i]), ]; @@ -534,7 +523,6 @@ export class CollectionSchemaView extends CollectionSubView() { if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); !shiftKey && this._selectedCells.push(doc); - this._selectedCells.forEach(d => console.log(d.title)) const index = this.rowIndex(doc); if (!this) return; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 98a16deea..a8affb0d9 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -87,7 +87,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { ContextMenu.Instance.displayMenu(x, y, undefined, false); } - get menuBackgroundColor(){ + @computed get menuBackgroundColor(){ if (this.Document._lockedSchemaEditing){ if (this._props.isSelected()) return '#B0D1E7' else return '#F5F5F5' @@ -95,14 +95,22 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { return '' } - get menuInfos() { + @computed get menuInfos() { const infos: Array = []; if (this.Document._lockedSchemaEditing) infos.push('lock'); if (this.Document._childrenSharedWithSchema) infos.push('star'); return infos; } - cleanupField = (field: string) => this.schemaView.cleanupComputedField(field) + @computed get isolatedSelection() { + const toReturn: [boolean, boolean] = [true, true]; + const selectedBelow: boolean = this.schemaView?._selectedDocs.includes(this.schemaView.draggedSpliceDocs.docs[this.rowIndex + 1]); + const selectedAbove: boolean = this.schemaView?._selectedDocs.includes(this.schemaView.draggedSpliceDocs.docs[this.rowIndex - 1]); + toReturn[0] = selectedAbove; + toReturn[1] = selectedBelow; + return toReturn; + } + setCursorIndex = (mouseY: number) => this.schemaView?.setRelCursorIndex(mouseY); selectedCol = () => this.schemaView._selectedCol; getFinfo = computedFn((fieldKey: string) => this.schemaView?.fieldInfos.get(fieldKey)); @@ -111,6 +119,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { selectedCells = () => this.schemaView?._selectedDocs; setColumnValues = (field: any, value: any) => this.schemaView?.setCellValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); + computeRowIndex = () => this.schemaView?.rowIndex(this.Document); render() { return (
() { row && this.schemaView?.addRowRef?.(this.Document, row); this._ref = row; }}> -
- {this.menuInfos.map(icn => )} -
() { ) } /> +
+ {this.menuInfos.map(icn => )} +
{this.schemaView?.columnKeys?.map((key, index) => ( () { setColumnValues={this.setColumnValues} oneLine={BoolCast(this.schemaDoc?._singleLine)} menuTarget={this.schemaView.MenuTarget} - cleanupField={this.cleanupField} transform={() => { const ind = index === this.schemaView.columnKeys.length - 1 ? this.schemaView.columnKeys.length - 3 : index; const x = this.schemaView?.displayColumnWidths.reduce((p, c, i) => (i <= ind ? p + c : p), 0); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 791465741..c8bd48019 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -13,7 +13,7 @@ import Select from 'react-select'; import { ClientUtils, StopEvent, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { DateField } from '../../../../fields/DateField'; -import { Doc, DocListCast, Field } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, IdToDoc } from '../../../../fields/Doc'; import { RichTextField } from '../../../../fields/RichTextField'; import { ColumnType } from '../../../../fields/SchemaHeaderField'; import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast, toList } from '../../../../fields/Types'; @@ -33,6 +33,7 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { CollectionSchemaView, FInfotoColType } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; +import { ContextMenu } from '../../ContextMenu'; export interface SchemaTableCellProps { Document: Doc; @@ -57,8 +58,8 @@ export interface SchemaTableCellProps { transform: () => Transform; autoFocus?: boolean; // whether to set focus on creation, othwerise wait for a click rootSelected?: () => boolean; - cleanupField: (field: string) => string; rowSelected: () => boolean; + isolatedSelection: [boolean, boolean]; } function selectedCell(props: SchemaTableCellProps) { @@ -137,13 +138,32 @@ export class SchemaTableCell extends ObservableReactComponent { + // const cm = ContextMenu.Instance; + // cm.clearItems(); + + + // } + + // parses a field from the "idToDoc(####)" format to DocumentId (d#) format for readability + cleanupField = (field: string) => { + const idPattern = /idToDoc\((.*?)\)/g; + let modField = field.slice(); + let matches; + let results = new Map(); + while ((matches = idPattern.exec(field)) !== null) {results.set(matches[0], matches[1].replace(/"/g, '')); } + results.forEach((id, funcId) => {modField = modField.replace(funcId, 'd' + (DocumentView.getDocViewIndex(IdToDoc(id))).toString());}) + if (!modField) modField = ''; + return modField; + } + @computed get defaultCellContent() { const { color, textDecoration, fieldProps, pointerEvents } = SchemaTableCell.renderProps(this._props); - return (
this._props.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} //TODO: feed this into parser that handles idToDoc + GetValue={() => this.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); @@ -201,6 +221,15 @@ export class SchemaTableCell extends ObservableReactComponent = []; + sides[0] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // left + sides[1] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // right + sides[2] = (!this._props.isolatedSelection[0] && selectedCell(this._props)) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top + sides[3] = (!this._props.isolatedSelection[1] && selectedCell(this._props)) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom + return sides; + } + render() { return (
{this.isDefault ? '' : this.content}
-- cgit v1.2.3-70-g09d2 From 60a4ccfe2ab6337c064da8a303336f1872f5e9a6 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 12 Jun 2024 21:16:17 -0400 Subject: cell value parser for highlighting cells used in equation works; need to implement actual VU --- src/client/views/EditableView.tsx | 16 ++++---- .../collectionSchema/CollectionSchemaView.tsx | 48 +++++++++++++++++++--- .../collectionSchema/SchemaColumnHeader.tsx | 6 ++- .../collections/collectionSchema/SchemaRowBox.tsx | 2 + .../collectionSchema/SchemaTableCell.tsx | 5 +++ 5 files changed, 63 insertions(+), 14 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index c05812e1a..f8d6596d8 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -11,6 +11,7 @@ import { FieldView, FieldViewProps } from './nodes/FieldView'; import { ObservableReactComponent } from './ObservableReactComponent'; import { OverlayView } from './OverlayView'; import { Padding } from 'browndash-components'; +import { SchemaFieldType } from './collections/collectionSchema/SchemaColumnHeader'; export interface EditableProps { /** @@ -56,7 +57,7 @@ export interface EditableProps { placeholder?: string; wrap?: string; // nowrap, pre-wrap, etc - schemaHeader?: boolean; + schemaFieldType?: SchemaFieldType; onClick?: () => void; updateAlt?: (newAlt: string) => void; updateSearch?: (value: string) => void; @@ -71,19 +72,18 @@ export interface EditableProps { export class EditableView extends ObservableReactComponent { private _ref = React.createRef(); private _inputref: HTMLInputElement | HTMLTextAreaElement | null = null; + private _disposers: { [name: string]: IReactionDisposer } = {}; _overlayDisposer?: () => void; - _editingDisposer?: IReactionDisposer; + _highlightsDisposer?: () => void; @observable _editing: boolean = false; constructor(props: EditableProps) { super(props); makeObservable(this); - this._editing = !!this._props.editing; - if (this._props.schemaHeader) this._editing = true; } componentDidMount(): void { - this._editingDisposer = reaction( + this._disposers.editing = reaction( () => this._editing, editing => { if (editing) { @@ -91,7 +91,7 @@ export class EditableView extends ObservableReactComponent { if (this._inputref?.value.startsWith('=') || this._inputref?.value.startsWith(':=')) { this._overlayDisposer?.(); this._overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); - } + } }); } else { this._overlayDisposer?.(); @@ -114,7 +114,7 @@ export class EditableView extends ObservableReactComponent { componentWillUnmount() { this._overlayDisposer?.(); - this._editingDisposer?.(); + this._disposers.editing?.(); this._inputref?.value && this.finalizeEdit(this._inputref.value, false, true, false); } @@ -287,7 +287,7 @@ export class EditableView extends ObservableReactComponent { staticDisplay = () => { let toDisplay; const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); - if (this._props.schemaHeader){ + if (this._props.schemaFieldType === SchemaFieldType.Header){ toDisplay = { + const index = this.columnKeys.indexOf(fieldKey); + console.log(doc.title) + const cell = this._rowEles.get(doc).children[1].children[index]; + return cell; + } + + findCellRefs = (text: string) => { + const pattern = /(this|d(\d+))\.(\w+)/g; + interface Match { docRef: string; field: string; } + + const matches: Match[] = []; + let match: RegExpExecArray | null; + + while ((match = pattern.exec(text)) !== null) { + const docRef = match[1] === 'this' ? match[1] : match[2]; + matches.push({ docRef, field: match[3] }); + } + + const cells: Array = []; + matches.forEach((match: Match) => { + const {docRef, field} = match; + const doc = DocumentManager.Instance.DocumentViews[Number(docRef)].Document; + if (this.columnKeys.includes(field)) {cells.push(this.getCellElement(doc, field))} + }) + + console.log(cells); + + return cells; + } + + + @action addRowRef = (doc: Doc, ref: HTMLDivElement) => this._rowEles.set(doc, ref); @@ -1012,22 +1046,26 @@ export class CollectionSchemaView extends CollectionSubView() { } }; - displayedSubCollectionDocs = (doc: Doc) => { + subCollectionDocs = (doc: Doc, displayed: boolean) => { const childDocs = DocListCast(doc[Doc.LayoutFieldKey(doc)]); - const displayedCollections = childDocs.filter(d => d.type === 'collection' && d._childrenSharedWithSchema); + let collections: Array = []; + if (displayed) collections = childDocs.filter(d => d.type === 'collection' && d._childrenSharedWithSchema); + else collections = childDocs.filter(d => d.type === 'collection' && !d._childrenSharedWithSchema); let toReturn: Doc[] = [...childDocs]; - displayedCollections.forEach(d => toReturn = toReturn.concat(this.displayedSubCollectionDocs(d))); + collections.forEach(d => toReturn = toReturn.concat(this.subCollectionDocs(d, displayed))); return toReturn; } - + @computed get docs() { let docsFromChildren: Doc[] = []; + const displayedCollections = this.childDocs.filter(d => d.type === 'collection' && d._childrenSharedWithSchema); displayedCollections.forEach(d => { - let docsNotAlreadyDisplayed = this.displayedSubCollectionDocs(d).filter(dc => !this._docs.includes(dc)); + let docsNotAlreadyDisplayed = this.subCollectionDocs(d, true).filter(dc => !this._docs.includes(dc)); docsFromChildren = docsFromChildren.concat(docsNotAlreadyDisplayed); }); let docs = this._docs.concat(docsFromChildren); + return docs; } diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 0fe0033d4..f0debaec2 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -24,6 +24,10 @@ import { FInfo } from '../../../documents/Documents'; import { ColumnType } from '../../../../fields/SchemaHeaderField'; import { IconButton, Size } from 'browndash-components'; +export enum SchemaFieldType { + Header, Cell +} + export interface SchemaColumnHeaderProps { Document: Doc; autoFocus?: boolean; @@ -131,7 +135,7 @@ export class SchemaColumnHeader extends ObservableReactComponent { if (SchemaColumnHeader.isDefaultField(this.fieldKey)) return ''; else if (this._altTitle) return this._altTitle; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 107e29754..f6d99b47e 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -121,6 +121,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { setColumnValues = (field: any, value: any) => this.schemaView?.setCellValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); + findCellRefs = (text: string) => this.schemaView?.findCellRefs(text); render() { return (
() {
{this.schemaView?.columnKeys?.map((key, index) => ( boolean; rowSelected: () => boolean; isolatedSelection: [boolean, boolean]; + getCellRefs: (text: string) => any; } function selectedCell(props: SchemaTableCellProps) { @@ -72,6 +73,9 @@ function selectedCell(props: SchemaTableCellProps) { @observer export class SchemaTableCell extends ObservableReactComponent { + + @observable _highlighted: boolean = false; + constructor(props: SchemaTableCellProps) { super(props); makeObservable(this); @@ -186,6 +190,7 @@ export class SchemaTableCell extends ObservableReactComponent Date: Thu, 13 Jun 2024 01:19:46 -0400 Subject: cell highlighting from equations WORKS! --- src/client/views/EditableView.tsx | 5 +++- .../collectionSchema/CollectionSchemaView.tsx | 30 ++++++++++++++++++++-- .../collections/collectionSchema/SchemaRowBox.tsx | 4 +-- .../collectionSchema/SchemaTableCell.tsx | 4 +-- 4 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index f8d6596d8..14af8febb 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -61,6 +61,7 @@ export interface EditableProps { onClick?: () => void; updateAlt?: (newAlt: string) => void; updateSearch?: (value: string) => void; + highlightCells?: (text: string) => void; } /** @@ -74,7 +75,6 @@ export class EditableView extends ObservableReactComponent { private _inputref: HTMLInputElement | HTMLTextAreaElement | null = null; private _disposers: { [name: string]: IReactionDisposer } = {}; _overlayDisposer?: () => void; - _highlightsDisposer?: () => void; @observable _editing: boolean = false; constructor(props: EditableProps) { @@ -91,11 +91,13 @@ export class EditableView extends ObservableReactComponent { if (this._inputref?.value.startsWith('=') || this._inputref?.value.startsWith(':=')) { this._overlayDisposer?.(); this._overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); + this._props.highlightCells?.(this._props.GetValue() ?? ''); } }); } else { this._overlayDisposer?.(); this._overlayDisposer = undefined; + this._props.highlightCells?.(''); } }, { fireImmediately: true } @@ -127,6 +129,7 @@ export class EditableView extends ObservableReactComponent { this._overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); } this._props.updateSearch && this._props.updateSearch(targVal); + this._props.highlightCells?.(targVal); }; @action diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 4d959e42c..4fc89488d 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -40,6 +40,7 @@ import { GetEffectiveAcl } from '../../../../fields/util'; import { ContextMenuProps } from '../../ContextMenuItem'; import { truncate } from 'lodash'; import { DocumentManager } from '../../../util/DocumentManager'; +import { TbHemispherePlus } from 'react-icons/tb'; const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore @@ -99,6 +100,8 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _colBeingDragged: boolean = false; @observable _colKeysFiltered: boolean = false; @observable _cellTags: ObservableMap = new ObservableMap>(); + @observable _highlightedCells: Array = []; + @observable _cellHighlightColors: ObservableMap = new ObservableMap(); @observable _docs: Doc[] = []; // target HTMLelement portal for showing a popup menu to edit cell values. @@ -508,12 +511,35 @@ export class CollectionSchemaView extends CollectionSubView() { if (this.columnKeys.includes(field)) {cells.push(this.getCellElement(doc, field))} }) - console.log(cells); - return cells; } + removeCellHighlights = () => { + this._highlightedCells.forEach(cell => cell.style.border = ''); + this._highlightedCells = []; + } + + highlightCells = (text: string) => { + this.removeCellHighlights(); + const randNum = (): number => {return Math.floor(Math.random() * (255 - 1));} + const randomRGBColor = (): string => { + const r = randNum(); const g = randNum(); const b = randNum(); // prettier-ignore + return `rgb(${r}, ${g}, ${b})`; + } + + const cellsToHighlight = this.findCellRefs(text); + this._highlightedCells = [...cellsToHighlight]; + this._highlightedCells.forEach(cell => { + if (!this._cellHighlightColors.has(cell)) {this._cellHighlightColors.set(cell, `solid 2px ${randomRGBColor()}`)} + cell.style.border = this._cellHighlightColors.get(cell); + }); + // const cellsToRemove = []; + // this._highlightedCells.forEach(cell => !cellsToHighlight.includes(cell) && cellsToRemove.push(cell)); + // this._highlightedCells = this._highlightedCells.filter(cell => cellsToHighlight.includes(cell)); + // const cellsToAdd = cellsToHighlight.filter(cell => !this._highlightedCells.includes(cell)); + // this._highlightedCells = this._highlightedCells.concat(cellsToAdd); + } @action addRowRef = (doc: Doc, ref: HTMLDivElement) => this._rowEles.set(doc, ref); diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index f6d99b47e..4902a49ff 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -121,7 +121,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { setColumnValues = (field: any, value: any) => this.schemaView?.setCellValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); - findCellRefs = (text: string) => this.schemaView?.findCellRefs(text); + highlightCells = (text: string) => this.schemaView?.highlightCells(text); render() { return (
() {
{this.schemaView?.columnKeys?.map((key, index) => ( boolean; rowSelected: () => boolean; isolatedSelection: [boolean, boolean]; - getCellRefs: (text: string) => any; + highlightCells: (text: string) => void; } function selectedCell(props: SchemaTableCellProps) { @@ -175,6 +175,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} @@ -190,7 +191,6 @@ export class SchemaTableCell extends ObservableReactComponent Date: Fri, 14 Jun 2024 14:50:43 -0400 Subject: func parser bug where multiple references to same doc didn't parse correctly fixed --- src/client/views/EditableView.tsx | 4 +++- .../views/collections/collectionSchema/CollectionSchemaView.tsx | 5 ----- src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 8 ++++---- 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 14af8febb..f94f4be86 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -323,7 +323,9 @@ export class EditableView extends ObservableReactComponent { {this.renderEditor()}
) : ( - this.renderEditor() +
+ {this.renderEditor()} +
); } setTimeout(() => this._props.autosuggestProps?.resetValue()); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 4fc89488d..ba2d2a764 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -534,11 +534,6 @@ export class CollectionSchemaView extends CollectionSubView() { if (!this._cellHighlightColors.has(cell)) {this._cellHighlightColors.set(cell, `solid 2px ${randomRGBColor()}`)} cell.style.border = this._cellHighlightColors.get(cell); }); - // const cellsToRemove = []; - // this._highlightedCells.forEach(cell => !cellsToHighlight.includes(cell) && cellsToRemove.push(cell)); - // this._highlightedCells = this._highlightedCells.filter(cell => cellsToHighlight.includes(cell)); - // const cellsToAdd = cellsToHighlight.filter(cell => !this._highlightedCells.includes(cell)); - // this._highlightedCells = this._highlightedCells.concat(cellsToAdd); } @action diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 50ec2f978..26dc9c3c2 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -154,10 +154,10 @@ export class SchemaTableCell extends ObservableReactComponent(); - while ((matches = idPattern.exec(field)) !== null) {results.set(matches[0], matches[1].replace(/"/g, '')); } - results.forEach((id, funcId) => {modField = modField.replace(funcId, 'd' + (DocumentView.getDocViewIndex(IdToDoc(id))).toString());}) - if (!modField) modField = ''; + let results = new Array<[id: string, func: string]>(); + while ((matches = idPattern.exec(field)) !== null) {results.push([matches[0], matches[1].replace(/"/g, '')]); } + results.forEach((idFuncPair) => {modField = modField.replace(idFuncPair[0], 'd' + (DocumentView.getDocViewIndex(IdToDoc(idFuncPair[1]))).toString());}) + if (modField.charAt(modField.length - 1) === ';') modField = modField.substring(0, modField.length - 1); return modField; } -- cgit v1.2.3-70-g09d2 From c472f9844ed2806f7965713cf618363210e37de1 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sat, 15 Jun 2024 00:08:00 -0400 Subject: text highlighting works with 'this.' format --- .../collectionSchema/CollectionSchemaView.tsx | 12 ++++------ .../collectionSchema/SchemaTableCell.tsx | 28 ++++++++++++---------- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index ac9b57414..d75f076d2 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -523,16 +523,13 @@ export class CollectionSchemaView extends CollectionSubView() { this.removeCellHighlights(); const randomRGBColor = (): string[] => { - let r; let g; let b; const brightness = 450; - r = Math.floor(Math.random() * 256); - g = Math.floor(Math.random() * Math.min(256, brightness - r)); - b = Math.floor(brightness - r - g); + const r = Math.floor(Math.random() * 256); + const g = Math.floor(Math.random() * Math.min(256, brightness - r)); + const b = Math.floor(brightness - r - g); const lightenedRGB = ClientUtils.lightenRGB(r, g, b, 65); - const rL = lightenedRGB[0]; - const gL = lightenedRGB[1]; - const bL = lightenedRGB[2]; + const rL = lightenedRGB[0]; const gL = lightenedRGB[1]; const bL = lightenedRGB[2]; // prettier-ignore const bgdRGB = {rL, gL, bL}; return new Array(`rgb(${r}, ${g}, ${b})`, `rgb(${bgdRGB.rL}, ${bgdRGB.gL}, ${bgdRGB.bL})`); @@ -542,7 +539,6 @@ export class CollectionSchemaView extends CollectionSubView() { this._highlightedCells = [...cellsToHighlight]; this._highlightedCells.forEach(cell => { const color = randomRGBColor(); - console.log('border: ' + color[0] + ' background: ' + color[1]) if (!this._cellHighlightColors.has(cell)) {this._cellHighlightColors.set(cell, new Array(`solid 2px ${color[0]}`, color[1]))} cell.style.border = this._cellHighlightColors.get(cell)[0]; cell.style.backgroundColor = this._cellHighlightColors.get(cell)[1]; diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 26dc9c3c2..69880b280 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -81,13 +81,11 @@ export class SchemaTableCell extends ObservableReactComponent { - // const cm = ContextMenu.Instance; - // cm.clearItems(); - - // } + adjustedHighlight = (field: string) => { + const pattern = /\bthis.\b/g; + const modField = field.replace(pattern, `d${this.docIndex}.`); + this._props.highlightCells(modField); + } // parses a field from the "idToDoc(####)" format to DocumentId (d#) format for readability cleanupField = (field: string) => { @@ -158,6 +155,11 @@ export class SchemaTableCell extends ObservableReactComponent {modField = modField.replace(idFuncPair[0], 'd' + (DocumentView.getDocViewIndex(IdToDoc(idFuncPair[1]))).toString());}) if (modField.charAt(modField.length - 1) === ';') modField = modField.substring(0, modField.length - 1); + + const selfRefPattern = `d${this.docIndex}.${this._props.fieldKey}` + const selfRefRegX = RegExp(selfRefPattern, 'g'); + if (selfRefRegX.exec(modField) !== null) { return 'Invalid'} + return modField; } @@ -175,7 +177,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} -- cgit v1.2.3-70-g09d2 From 69153ed435cbbc10637563b8bb576a80f8c0693f Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:07:00 -0400 Subject: schema cell editable field class started --- src/client/views/EditableView.tsx | 13 +- .../collectionSchema/SchemaCellField.tsx | 195 +++++++++++++++++++++ .../collectionSchema/SchemaTableCell.tsx | 4 +- 3 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 src/client/views/collections/collectionSchema/SchemaCellField.tsx (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index f94f4be86..f5271f749 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -58,6 +58,7 @@ export interface EditableProps { wrap?: string; // nowrap, pre-wrap, etc schemaFieldType?: SchemaFieldType; + prohibitedText?: Array; onClick?: () => void; updateAlt?: (newAlt: string) => void; updateSearch?: (value: string) => void; @@ -203,8 +204,13 @@ export class EditableView extends ObservableReactComponent { } }; + // checkForInvalidText = (text: string) => { + // const regX = new RegExp(new Array(...this._props.prohibitedText), 'g') + // } + @action finalizeEdit(value: string, shiftDown: boolean, lostFocus: boolean, enterKey: boolean) { + //if (invalid) raise error if (this._props.SetValue(value, shiftDown, enterKey)) { this._editing = false; this._props.isEditingCallback?.(false); @@ -252,7 +258,7 @@ export class EditableView extends ObservableReactComponent { onChange: this._props.autosuggestProps.onChange, }} /> - ) : this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? ( + ) : ( this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? ( { this._inputref = r; }} // prettier-ignore @@ -284,7 +290,7 @@ export class EditableView extends ObservableReactComponent { onClick={this.stopPropagation} onPointerUp={this.stopPropagation} /> - ); + )); } staticDisplay = () => { @@ -319,8 +325,7 @@ export class EditableView extends ObservableReactComponent { if ((this._editing && gval !== undefined)) { return this._props.sizeToContent ? (
-
{gval}
- {this.renderEditor()} +
{this.renderEditor()}
) : (
diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx new file mode 100644 index 000000000..5f758683d --- /dev/null +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -0,0 +1,195 @@ +import { IReactionDisposer, action, makeObservable, observable, reaction, runInAction } from "mobx"; +import { ObservableReactComponent } from "../../ObservableReactComponent"; +import { observer } from "mobx-react"; +import { OverlayView } from "../../OverlayView"; +import { DocumentIconContainer } from "../../nodes/DocumentIcon"; +import React, { FormEvent } from "react"; +import { FieldView, FieldViewProps } from "../../nodes/FieldView"; +import { ObjectField } from "../../../../fields/ObjectField"; + +export interface SchemaCellFieldProps { + contents: any; + fieldContents?: FieldViewProps; + editing?: boolean; + oneLine?: boolean; + highlightCells?: (text: string) => void; + GetValue(): string | undefined; + SetValue(value: string, shiftDown?: boolean, enterKey?: boolean): boolean; +} + +@observer +export class SchemaCellField extends ObservableReactComponent { + + private _disposers: { [name: string]: IReactionDisposer } = {}; + private _inputref: HTMLDivElement | null = null; + _overlayDisposer?: () => void; + @observable _editing: boolean = false; + + constructor(props: SchemaCellFieldProps) { + super(props); + makeObservable(this); + } + + componentDidMount(): void { + this._disposers.editing = reaction( + () => this._editing, + editing => { + if (editing) { + setTimeout(() => { + if (this._inputref?.innerText.startsWith('=') || this._inputref?.innerText.startsWith(':=')) { + this._overlayDisposer?.(); + this._overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); + this._props.highlightCells?.(this._props.GetValue() ?? ''); + } + }); + } else { + this._overlayDisposer?.(); + this._overlayDisposer = undefined; + this._props.highlightCells?.(''); + } + }, + { fireImmediately: true } + ); + } + + componentDidUpdate(prevProps: Readonly) { + super.componentDidUpdate(prevProps); + if (this._editing && this._props.editing === false) { + this._inputref?.innerText && this.finalizeEdit(this._inputref.innerText, false, true, false); + } else + runInAction(() => { + if (this._props.editing !== undefined) this._editing = this._props.editing; + }); + } + + componentWillUnmount(): void { + this._overlayDisposer?.(); + this._disposers.editing?.(); + this._inputref?.innerText && this.finalizeEdit(this._inputref.innerText, false, true, false); + } + + @action + setIsFocused = (value: boolean) => { + const wasFocused = this._editing; + this._editing = value; + return wasFocused !== this._editing; + }; + + onChange = (e: FormEvent) => { + const targVal = e.currentTarget.innerText; + if (!(targVal.startsWith(':=') || targVal.startsWith('='))) { + this._overlayDisposer?.(); + this._overlayDisposer = undefined; + } else if (!this._overlayDisposer) { + this._overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); + } + this._props.highlightCells?.(targVal); + }; + + @action + onKeyDown = (e: React.KeyboardEvent) => { + if (e.nativeEvent.defaultPrevented) return; // hack .. DashFieldView grabs native events, but react ignores stoppedPropagation and preventDefault, so we need to check it here + switch (e.key) { + case 'Tab': + e.stopPropagation(); + this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, false); + break; + case 'Backspace': + e.stopPropagation(); + break; + case 'Enter': + e.stopPropagation(); + if (!e.ctrlKey) { + this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, true); + } + break; + case 'Escape': + e.stopPropagation(); + this._editing = false; + break; + case 'ArrowUp': case 'ArrowDown': case 'ArrowLeft': case 'ArrowRight': //prettier-ignore + e.stopPropagation(); + break; + case 'Shift': case 'Alt': case 'Meta': case 'Control': case ':': //prettier-ignore + break; + // eslint-disable-next-line no-fallthrough + default: + break; + } + }; + + + @action + onClick = (e?: React.MouseEvent) => { + if (this._props.editing !== false) { + e?.nativeEvent.stopPropagation(); + this._editing = true; + } + }; + + @action + finalizeEdit(value: string, shiftDown: boolean, lostFocus: boolean, enterKey: boolean) { + //if (invalid) raise error + if (this._props.SetValue(value, shiftDown, enterKey)) { + this._editing = false; + } else { + this._editing = false; + !lostFocus && + setTimeout( + action(() => { + this._editing = true; + }), + 0 + ); + } + } + + staticDisplay = () => { + return + { + // eslint-disable-next-line react/jsx-props-no-spreading + this._props.fieldContents ? : this.props.contents ? this._props.contents?.valueOf() : '' + } + + } + + renderEditor = () => { + return ( +
{ this._inputref = r; }} + style={{ overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, }} + onBlur={e => this.finalizeEdit(this._inputref ? this._inputref.innerText : '', false, true, false)} + autoFocus + onInput={this.onChange} + onKeyDown={this.onKeyDown} + onPointerDown={e => e.stopPropagation} + onClick={e => e.stopPropagation} + onPointerUp={e => e.stopPropagation} + > +
+ ); + } + + render() { + const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); + if ((this._editing && gval !== undefined)) { + return
{this.renderEditor()}
; + } else return ( + this._props.contents instanceof ObjectField ? null : ( +
+ {this.staticDisplay()} +
+ ) + ); + } + +} \ No newline at end of file diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 69880b280..79f9067e2 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -34,6 +34,7 @@ import { CollectionSchemaView, FInfotoColType } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { ContextMenu } from '../../ContextMenu'; +import { SchemaCellField } from './SchemaCellField'; export interface SchemaTableCellProps { Document: Doc; @@ -176,11 +177,10 @@ export class SchemaTableCell extends ObservableReactComponent - selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} - allowCRs={this._props.allowCRs} contents={undefined} fieldContents={fieldProps} editing={selectedCell(this._props) ? undefined : false} -- cgit v1.2.3-70-g09d2 From 50021902948840e87da1faf74f6403e25e667580 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:58:18 -0400 Subject: persistent sort option added, still need UI indication; some header bugs/weirdness fixed --- src/client/views/EditableView.tsx | 10 +++- .../collectionSchema/CollectionSchemaView.tsx | 69 +++++++++++++++++----- .../collectionSchema/SchemaColumnHeader.tsx | 20 ++++++- .../collectionSchema/SchemaTableCell.tsx | 2 +- 4 files changed, 80 insertions(+), 21 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index f5271f749..78977bcb8 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -239,6 +239,12 @@ export class EditableView extends ObservableReactComponent { return wasFocused !== this._editing; }; + @action + setIsEditing = (value: boolean) => { + this._editing = value; + return this._editing; + } + renderEditor() { return this._props.autosuggestProps ? ( {
{this.renderEditor()}
) : ( -
- {this.renderEditor()} -
+ this.renderEditor() ); } setTimeout(() => this._props.autosuggestProps?.resetValue()); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index d75f076d2..c66623bda 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -41,6 +41,7 @@ import { ContextMenuProps } from '../../ContextMenuItem'; import { truncate } from 'lodash'; import { DocumentManager } from '../../../util/DocumentManager'; import { TbHemispherePlus } from 'react-icons/tb'; +import { docs_v1 } from 'googleapis'; const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore @@ -400,6 +401,7 @@ export class CollectionSchemaView extends CollectionSubView() { @action dragColumn = (e: PointerEvent, index: number) => { + this.closeColumnMenu(); this._draggedColIndex = index; this._colBeingDragged = true; const dragData = new DragManager.ColumnDragData(index); @@ -584,6 +586,7 @@ export class CollectionSchemaView extends CollectionSubView() { @action selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { + this.closeColumnMenu(); if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); !shiftKey && this._selectedCells.push(doc); @@ -839,10 +842,28 @@ export class CollectionSchemaView extends CollectionSubView() { const cm = ContextMenu.Instance; cm.clearItems(); + const fieldSortedAsc = (this.sortField === this.columnKeys[index] && !this.sortDesc); + const fieldSortedDesc = (this.sortField === this.columnKeys[index] && this.sortDesc); const revealOptions = cm.findByDescription('Sort column') const sortOptions: ContextMenuProps[] = revealOptions && revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : []; sortOptions.push({description: 'Sort A-Z', event: () => this.sortDocs(this._docs, this.columnKeys[index], false), icon: 'arrow-down-a-z',}); // prettier-ignore sortOptions.push({description: 'Sort Z-A', event: () => this.sortDocs(this._docs, this.columnKeys[index], true), icon: 'arrow-up-z-a'}); // prettier-ignore + sortOptions.push({ + description: 'Persistent Sort A-Z', + event: () => { + if (fieldSortedAsc){ + this.setColumnSort(undefined) + } else this.setColumnSort(this.columnKeys[index], false) + }, + icon: fieldSortedAsc ? 'lock' : 'lock-open'}); // prettier-ignore + sortOptions.push({ + description: 'Persistent Sort Z-A', + event: () => { + if (fieldSortedDesc){ + this.setColumnSort(undefined) + } else this.setColumnSort(this.columnKeys[index], true) + }, + icon: fieldSortedDesc ? 'lock' : 'lock-open'}); // prettier-ignore cm.addItem({ description: `Change field`, @@ -1100,25 +1121,45 @@ export class CollectionSchemaView extends CollectionSubView() { } @computed get docsWithDrag() { - const draggedDocs = this.isContentActive() ? DragManager.docsBeingDragged : []; - let docs = [...this.docs]; - docs = docs.filter(d => !draggedDocs.includes(d)); - docs.splice(this.rowDropIndex, 0, ...draggedDocs); + let docs = this._docs; + if (this.sortField){ + const field = StrCast(this.layoutDoc.sortField); + const desc = BoolCast(this.layoutDoc.sortDesc); // is this an ascending or descending sort + docs = this._docs.slice().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 FieldType); + const bStr = Field.toString(docB[field] as FieldType); + let out = 0; + if (aStr < bStr) out = -1; + if (aStr > bStr) out = 1; + if (desc) out *= -1; + return out; + }); + } else { + const draggedDocs = this.isContentActive() ? DragManager.docsBeingDragged : []; + docs = docs.filter(d => !draggedDocs.includes(d)); + docs.splice(this.rowDropIndex, 0, ...draggedDocs); + } + return { docs }; } @action sortDocs = (docs: Doc[], field: string, desc: boolean) => { - this._docs = docs.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 FieldType); - const bStr = Field.toString(docB[field] as FieldType); - let out = 0; - if (aStr < bStr) out = -1; - if (aStr > bStr) out = 1; - if (desc) out *= -1; - return out; - }); + const collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'}); + this._docs = this._docs.slice().sort((docA, docB) => collator.compare(Field.toString(docA[field] as FieldType), Field.toString(docB[field] as FieldType))); + + + // this._docs = docs.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 FieldType); + // const bStr = Field.toString(docB[field] as FieldType); + // let out = 0; + // if (aStr < bStr) out = -1; + // if (aStr > bStr) out = 1; + // if (desc) out *= -1; + // return out; + // }); } rowHeightFunc = () => (BoolCast(this.layoutDoc._schema_singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight); diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index f0debaec2..d16cde1f8 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -54,6 +54,7 @@ export interface SchemaColumnHeaderProps { @observer export class SchemaColumnHeader extends ObservableReactComponent { + private _inputRef: EditableView | null = null; @observable _altTitle: string | undefined = undefined; @observable _showMenuIcon: boolean = false; @@ -118,14 +119,17 @@ export class SchemaColumnHeader extends ObservableReactComponent {SchemaColumnHeader.isDefaultField(this.fieldKey) && this.openKeyDropdown()}} + return
{ + SchemaColumnHeader.isDefaultField(this.fieldKey) && this.openKeyDropdown(); + this._props.schemaView.deselectAllCells(); + }} style={{ color, width: '100%', pointerEvents, }}> this._props.autoFocus && r?.setIsFocused(true)} + ref={r => {this._inputRef = r; this._props.autoFocus && r?.setIsFocused(true)}} oneLine={true} allowCRs={false} contents={undefined} @@ -215,7 +219,17 @@ export class SchemaColumnHeader extends ObservableReactComponent {this.handlePointerEnter()}} onPointerLeave={() => {this.handlePointerLeave()}} - onPointerDown={this.setupDrag} + onPointerDown={e => { + this.setupDrag(e); + setupMoveUpEvents( + this, + e, + e => {return this._inputRef?.setIsEditing(false) ?? false}, + emptyFunction, + emptyFunction, + ); + } + } ref={col => { if (col) { this._props.setColRef(this._props.columnIndex, col); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 79f9067e2..17fff7bf1 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -177,7 +177,7 @@ export class SchemaTableCell extends ObservableReactComponent - selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} -- cgit v1.2.3-70-g09d2 From d207cf565968167c59b16baf6ca5ce2543c680ea Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 20 Jun 2024 01:57:07 -0400 Subject: cursor position consistency for schema cell field --- .../collectionSchema/CollectionSchemaView.tsx | 4 +- .../collectionSchema/SchemaCellField.tsx | 86 ++++++++++++++++++---- .../collectionSchema/SchemaTableCell.tsx | 3 +- 3 files changed, 74 insertions(+), 19 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 1d9245206..c287b7d44 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -478,7 +478,6 @@ export class CollectionSchemaView extends CollectionSubView() { this._colEles.forEach((colRef, i) => { const edgeStyle = i === index ? `solid 2px ${Colors.MEDIUM_BLUE}` : ''; const sorted = i === this.columnKeys.indexOf(this.sortField); - console.log(sorted) const cellEles = [ colRef, ...this.docsWithDrag.docs @@ -497,7 +496,7 @@ export class CollectionSchemaView extends CollectionSubView() { highlightSortedColumn = (field?: string, descending?: boolean) => { let index = -1; let highlightColors: string[] = []; - const rowCount: number = this._rowEles.size + 1; + const rowCount: number = this._docs.length + 1; if (field || this.sortField){ index = this.columnKeys.indexOf(field || this.sortField); const increment: number = 100/rowCount; @@ -530,7 +529,6 @@ export class CollectionSchemaView extends CollectionSubView() { getCellElement = (doc: Doc, fieldKey: string) => { const index = this.columnKeys.indexOf(fieldKey); - console.log(doc.title) const cell = this._rowEles.get(doc).children[1].children[index]; return cell; } diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 5f758683d..3af3b1d61 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -22,8 +22,10 @@ export class SchemaCellField extends ObservableReactComponent void; @observable _editing: boolean = false; + @observable _displayedContent = ''; constructor(props: SchemaCellFieldProps) { super(props); @@ -50,12 +52,14 @@ export class SchemaCellField extends ObservableReactComponent) { super.componentDidUpdate(prevProps); if (this._editing && this._props.editing === false) { - this._inputref?.innerText && this.finalizeEdit(this._inputref.innerText, false, true, false); + this.finalizeEdit(false, true, false); } else runInAction(() => { if (this._props.editing !== undefined) this._editing = this._props.editing; @@ -65,9 +69,14 @@ export class SchemaCellField extends ObservableReactComponent { + this._displayedContent = content; + }; + @action setIsFocused = (value: boolean) => { const wasFocused = this._editing; @@ -75,7 +84,52 @@ export class SchemaCellField extends ObservableReactComponent) => { + get cursorPosition() { + const selection = window.getSelection(); + if (!selection || selection.rangeCount === 0 || !this._inputref) return null; + + const range = selection.getRangeAt(0); + const adjRange = range.cloneRange(); + + adjRange.selectNodeContents(this._inputref); + adjRange.setEnd(range.startContainer, range.startOffset); + + return adjRange.toString().length; + } + + restoreCursorPosition = (position: number | null) => { + const selection = window.getSelection(); + if (!selection || position === null || !this._inputref) return; + + const range = document.createRange(); + range.setStart(this._inputref, 0); + range.collapse(true); + + let currentPos = 0; + const setRange = (nodes: NodeList) => { + for (let i = 0; i < nodes.length; ++i) { + const node = nodes[i]; + + if (node.nodeType === Node.TEXT_NODE) { + if (!node.textContent) return; + const nextPos = currentPos + node.textContent.length; + if (position <= nextPos) { + range.setStart(node, position - currentPos); + range.collapse(true); + selection.removeAllRanges(); + selection.addRange(range); + return true; + } + currentPos = nextPos; + + } else if ((node.nodeType === Node.ELEMENT_NODE) && (setRange(node.childNodes))) return true; + } + return false; + } + }; + + onChange = (e: FormEvent) => { + const cursorPos = this.cursorPosition; const targVal = e.currentTarget.innerText; if (!(targVal.startsWith(':=') || targVal.startsWith('='))) { this._overlayDisposer?.(); @@ -83,6 +137,9 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); } + this._content = targVal; + this.setContent(targVal); + setTimeout(() => this.restoreCursorPosition(cursorPos), 0); this._props.highlightCells?.(targVal); }; @@ -92,7 +149,7 @@ export class SchemaCellField extends ObservableReactComponent : this.props.contents ? this._props.contents?.valueOf() : '' } - } + }; renderEditor = () => { return ( -
{ this._inputref = r; }} style={{ overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, }} - onBlur={e => this.finalizeEdit(this._inputref ? this._inputref.innerText : '', false, true, false)} + onBlur={e => this.finalizeEdit(false, true, false)} autoFocus onInput={this.onChange} onKeyDown={this.onKeyDown} onPointerDown={e => e.stopPropagation} onClick={e => e.stopPropagation} onPointerUp={e => e.stopPropagation} + dangerouslySetInnerHTML={{ __html: `${this._displayedContent}` }} >
); - } + }; render() { const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); if ((this._editing && gval !== undefined)) { - return
{this.renderEditor()}
; + return
{this.renderEditor()}
; } else return ( this._props.contents instanceof ObjectField ? null : (
- selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} @@ -251,7 +251,6 @@ export class SchemaTableCell extends ObservableReactComponent Date: Thu, 20 Jun 2024 14:33:28 -0400 Subject: some progress on eq text highlighting --- .../collectionSchema/CollectionSchemaView.scss | 5 +++ .../collectionSchema/CollectionSchemaView.tsx | 4 ++- .../collectionSchema/SchemaCellField.tsx | 37 +++++++++++++++++----- .../collections/collectionSchema/SchemaRowBox.tsx | 6 ++++ .../collectionSchema/SchemaTableCell.tsx | 6 +++- 5 files changed, 48 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index d1f1e3a13..6b53eb1cc 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -313,3 +313,8 @@ } } +.schemaField-editing { + outline: none; +} + + diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index c287b7d44..5c8a84163 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -533,7 +533,7 @@ export class CollectionSchemaView extends CollectionSubView() { return cell; } - findCellRefs = (text: string) => { + findCellRefs = (text: string, retRawMatches?: boolean) => { const pattern = /(this|d(\d+))\.(\w+)/g; interface Match { docRef: string; field: string; } @@ -545,6 +545,8 @@ export class CollectionSchemaView extends CollectionSubView() { matches.push({ docRef, field: match[3] }); } + if (retRawMatches) return matches; + const cells: Array = []; matches.forEach((match: Match) => { const {docRef, field} = match; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 3af3b1d61..4ba8c8469 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -15,6 +15,7 @@ export interface SchemaCellFieldProps { highlightCells?: (text: string) => void; GetValue(): string | undefined; SetValue(value: string, shiftDown?: boolean, enterKey?: boolean): boolean; + func: (text: string, raw: boolean) => HTMLDivElement[] | []; } @observer @@ -72,10 +73,25 @@ export class SchemaCellField extends ObservableReactComponent { + const matches = this._props.func(content, true); + const cells = this._props.func(content, false); + let chunkedText = content; + let matchNum = 0; + matches.forEach((docRef, field) => { + console.log('cell: ' + cells[matchNum] + ' border: ' + cells[matchNum].style.borderTop) + chunkedText = chunkedText.replace(`d5.type`, `d5.type`); + ++matchNum; + }) + return chunkedText; + } + @action setContent = (content: string) => { - this._displayedContent = content; - }; + console.log(this.chunkContent(content)); + this._displayedContent = this.chunkContent(content); + console.log('displayed: ' + this._displayedContent); + } @action setIsFocused = (value: boolean) => { @@ -126,10 +142,13 @@ export class SchemaCellField extends ObservableReactComponent) => { const cursorPos = this.cursorPosition; + const prevVal = this._content; const targVal = e.currentTarget.innerText; if (!(targVal.startsWith(':=') || targVal.startsWith('='))) { this._overlayDisposer?.(); @@ -138,8 +157,10 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); } this._content = targVal; - this.setContent(targVal); - setTimeout(() => this.restoreCursorPosition(cursorPos), 0); + if (this._props.func(targVal, true).length > this._props.func(prevVal, true).length) { + this.setContent(targVal); + setTimeout(() => this.restoreCursorPosition(cursorPos), 0); + } this._props.highlightCells?.(targVal); }; @@ -208,15 +229,15 @@ export class SchemaCellField extends ObservableReactComponent : this.props.contents ? this._props.contents?.valueOf() : '' } - }; + } renderEditor = () => { return (
{ this._inputref = r; }} - style={{ overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, }} + style={{ outline: 'none', overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, }} onBlur={e => this.finalizeEdit(false, true, false)} autoFocus onInput={this.onChange} @@ -228,7 +249,7 @@ export class SchemaCellField extends ObservableReactComponent
); - }; + } render() { const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 4902a49ff..121605a2b 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -122,6 +122,10 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); highlightCells = (text: string) => this.schemaView?.highlightCells(text); + equationHighlightRef = (text: string) => { + + } + eqHighlightFunc = (text: string, raw: boolean) => {return this.schemaView.findCellRefs(text, raw)}; render() { return (
() {
{this.schemaView?.columnKeys?.map((key, index) => ( boolean; isolatedSelection: [boolean, boolean]; highlightCells: (text: string) => void; + equationHighlightRef: ObservableMap; + func: (text: string, raw: boolean) => HTMLDivElement[] | []; + } function selectedCell(props: SchemaTableCellProps) { @@ -179,6 +182,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} contents={undefined} -- cgit v1.2.3-70-g09d2 From 83a2f119bf908d07e08ac89171e73d2211e1eb8f Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:50:00 -0400 Subject: eq highlight working 70% --- .../collectionSchema/SchemaCellField.tsx | 35 +++++++++++++++------- .../collections/collectionSchema/SchemaRowBox.tsx | 2 +- .../collectionSchema/SchemaTableCell.tsx | 1 + 3 files changed, 27 insertions(+), 11 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 4ba8c8469..6663fb68f 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -6,12 +6,15 @@ import { DocumentIconContainer } from "../../nodes/DocumentIcon"; import React, { FormEvent } from "react"; import { FieldView, FieldViewProps } from "../../nodes/FieldView"; import { ObjectField } from "../../../../fields/ObjectField"; +import { Doc } from "../../../../fields/Doc"; +import { DocumentView } from "../../nodes/DocumentView"; export interface SchemaCellFieldProps { contents: any; fieldContents?: FieldViewProps; editing?: boolean; oneLine?: boolean; + Document: Doc; highlightCells?: (text: string) => void; GetValue(): string | undefined; SetValue(value: string, shiftDown?: boolean, enterKey?: boolean): boolean; @@ -33,7 +36,11 @@ export class SchemaCellField extends ObservableReactComponent this._editing, editing => { @@ -43,6 +50,7 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); this._props.highlightCells?.(this._props.GetValue() ?? ''); + this.setContent(this._content); } }); } else { @@ -53,8 +61,6 @@ export class SchemaCellField extends ObservableReactComponent) { @@ -74,13 +80,24 @@ export class SchemaCellField extends ObservableReactComponent { - const matches = this._props.func(content, true); + const pattern = /(this|d(\d+))\.(\w+)/g; + interface Match { docRef: string; field: string; } + + const matches: Match[] = []; + let match: RegExpExecArray | null; + + while ((match = pattern.exec(content)) !== null) { + const docRef = match[1] === 'this' ? match[1] : match[2]; + matches.push({ docRef, field: match[3] }); + } + const cells = this._props.func(content, false); let chunkedText = content; let matchNum = 0; - matches.forEach((docRef, field) => { - console.log('cell: ' + cells[matchNum] + ' border: ' + cells[matchNum].style.borderTop) - chunkedText = chunkedText.replace(`d5.type`, `d5.type`); + matches.forEach((match: Match) => { + const {docRef, field} = match; + // const refToUse = docRef === 'this' ? `${this.docIndex}` : docRef; + chunkedText = chunkedText.replace(`d${docRef}.${field}`, `d${docRef}.${field}`); ++matchNum; }) return chunkedText; @@ -88,9 +105,7 @@ export class SchemaCellField extends ObservableReactComponent { - console.log(this.chunkContent(content)); this._displayedContent = this.chunkContent(content); - console.log('displayed: ' + this._displayedContent); } @action @@ -157,11 +172,11 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); } this._content = targVal; + this._props.highlightCells?.(targVal); if (this._props.func(targVal, true).length > this._props.func(prevVal, true).length) { this.setContent(targVal); setTimeout(() => this.restoreCursorPosition(cursorPos), 0); } - this._props.highlightCells?.(targVal); }; @action @@ -245,7 +260,7 @@ export class SchemaCellField extends ObservableReactComponent e.stopPropagation} onClick={e => e.stopPropagation} onPointerUp={e => e.stopPropagation} - dangerouslySetInnerHTML={{ __html: `${this._displayedContent}` }} + dangerouslySetInnerHTML={{ __html: this._displayedContent }} >
); diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 121605a2b..c0ad95141 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -131,7 +131,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() {
this.setCursorIndex(e.clientY)} - style={{ height: this._props.PanelHeight(), backgroundColor: this._props.isSelected() ? Colors.LIGHT_BLUE : undefined }} + style={{ height: this._props.PanelHeight()}} 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 74ee46065..3233e363a 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -181,6 +181,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} -- cgit v1.2.3-70-g09d2 From 24fad06cbd2e273bb6729f21956e35243e602bb7 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:37:47 -0400 Subject: fixed bug where equation didn't save in cell field on reloading (batching issue) --- .../views/collections/collectionSchema/CollectionSchemaView.tsx | 2 +- src/client/views/collections/collectionSchema/SchemaCellField.tsx | 7 +++++-- src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 6838662c7..308520154 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -587,7 +587,7 @@ export class CollectionSchemaView extends CollectionSubView() { const color = randomRGBColor(); const doc = info[0]; const field = info[1]; - const key = `${doc}_${field}`; + const key = `${doc[Id]}_${field}`; const cell = this.getCellElement(doc, field); if (!this._cellHighlightColors.has(key)) {this._cellHighlightColors.set(key, new Array(`solid 2px ${color[0]}`, color[1]))} cell.style.border = this._cellHighlightColors.get(key)[0]; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 6663fb68f..dcfa4f6f2 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -39,8 +39,10 @@ export class SchemaCellField extends ObservableReactComponent { + this._content = this._props.GetValue() ?? ''; + this.setContent(this._content); + }, 0); //must be moved to end of batch or else other docs aren't loaded, so render as d-1 in function this._disposers.editing = reaction( () => this._editing, editing => { @@ -50,6 +52,7 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); this._props.highlightCells?.(this._props.GetValue() ?? ''); + if (this._props.Document.type === 'collection') console.log('highlight: ' + this._props.GetValue()) this.setContent(this._content); } }); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 3233e363a..94fd9ec7d 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -152,6 +152,7 @@ export class SchemaTableCell extends ObservableReactComponent { + if (field === ':=d6.type + d4.type + d3.type') console.log(true) const idPattern = /idToDoc\((.*?)\)/g; let modField = field.slice(); let matches; -- cgit v1.2.3-70-g09d2 From 7f9d92b3e1d0ca433c732936eae767095c9a5e7f Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:47:12 -0400 Subject: work on cell field (numerous bugs fixed: spaces now make new divs, invalid refs no longer break things, valid->invalid ref causes update properly) --- .../collectionSchema/CollectionSchemaView.tsx | 9 ++- .../collectionSchema/SchemaCellField.tsx | 79 ++++++++++++++-------- .../collections/collectionSchema/SchemaRowBox.tsx | 5 +- .../collectionSchema/SchemaTableCell.tsx | 4 +- 4 files changed, 59 insertions(+), 38 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 308520154..9c4eda3b8 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -533,7 +533,7 @@ export class CollectionSchemaView extends CollectionSubView() { return cell; } - findCellRefs = (text: string, retRawMatches?: boolean) => { + findCellRefs = (text: string) => { const pattern = /(this|d(\d+))\.(\w+)/g; interface Match { docRef: string; field: string; } @@ -545,13 +545,12 @@ export class CollectionSchemaView extends CollectionSubView() { matches.push({ docRef, field: match[3] }); } - if (retRawMatches) return matches; - const cells: Array = []; matches.forEach((match: Match) => { const {docRef, field} = match; - const doc = DocumentManager.Instance.DocumentViews[Number(docRef)].Document; - if (this.columnKeys.includes(field)) {cells.push([doc, field])} + const docView = DocumentManager.Instance.DocumentViews[Number(docRef)]; + const doc = docView?.Document ?? undefined; + if (this.columnKeys.includes(field) && this._docs.includes(doc)) {cells.push([doc, field])} }) return cells; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index dcfa4f6f2..e2aa27a95 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -18,7 +18,7 @@ export interface SchemaCellFieldProps { highlightCells?: (text: string) => void; GetValue(): string | undefined; SetValue(value: string, shiftDown?: boolean, enterKey?: boolean): boolean; - func: (text: string, raw: boolean) => HTMLDivElement[] | []; + getCells: (text: string) => HTMLDivElement[] | []; } @observer @@ -26,7 +26,7 @@ export class SchemaCellField extends ObservableReactComponent void; @observable _editing: boolean = false; @observable _displayedContent = ''; @@ -40,8 +40,8 @@ export class SchemaCellField extends ObservableReactComponent { - this._content = this._props.GetValue() ?? ''; - this.setContent(this._content); + this._unrenderedContent = this._props.GetValue() ?? ''; + this.setContent(this._unrenderedContent, true); }, 0); //must be moved to end of batch or else other docs aren't loaded, so render as d-1 in function this._disposers.editing = reaction( () => this._editing, @@ -52,8 +52,7 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); this._props.highlightCells?.(this._props.GetValue() ?? ''); - if (this._props.Document.type === 'collection') console.log('highlight: ' + this._props.GetValue()) - this.setContent(this._content); + this.setContent(this._unrenderedContent, true); } }); } else { @@ -82,33 +81,44 @@ export class SchemaCellField extends ObservableReactComponent { - const pattern = /(this|d(\d+))\.(\w+)/g; - interface Match { docRef: string; field: string; } + makeSpans = (content: string) => { + let chunkedText = content; + chunkedText = chunkedText.replace(/ +/g, (match) => { + const spanSpaces = ' '.repeat(match.length); + return `${spanSpaces}`; + }); - const matches: Match[] = []; + const pattern = /(this|d(\d+))\.(\w+)/g; + const matches: string[] = []; let match: RegExpExecArray | null; + const cells: Map = new Map(); + while ((match = pattern.exec(content)) !== null) { - const docRef = match[1] === 'this' ? match[1] : match[2]; - matches.push({ docRef, field: match[3] }); + const cell = this._props.getCells(match[0]); + if (cell.length) { + matches.push(match[0]); + cells.set(match[0], cell[0]) + } } - const cells = this._props.func(content, false); - let chunkedText = content; let matchNum = 0; - matches.forEach((match: Match) => { - const {docRef, field} = match; + matches.forEach((match: string) => { // const refToUse = docRef === 'this' ? `${this.docIndex}` : docRef; - chunkedText = chunkedText.replace(`d${docRef}.${field}`, `d${docRef}.${field}`); + chunkedText = chunkedText.replace(match, `${match}`); ++matchNum; }) + return chunkedText; } @action - setContent = (content: string) => { - this._displayedContent = this.chunkContent(content); + setContent = (content: string, restoreCursorPos?: boolean) => { + this._displayedContent = this.makeSpans(content); + if (restoreCursorPos) { + const cursorPos = this.cursorPosition; + setTimeout(() => this.restoreCursorPosition(cursorPos), 0); + } } @action @@ -164,9 +174,13 @@ export class SchemaCellField extends ObservableReactComponent { + if (this._props.getCells(currVal).length !== this._props.getCells(prevVal).length) return true; + //if (contains self-ref pattern) + }; + onChange = (e: FormEvent) => { - const cursorPos = this.cursorPosition; - const prevVal = this._content; + const prevVal = this._unrenderedContent; const targVal = e.currentTarget.innerText; if (!(targVal.startsWith(':=') || targVal.startsWith('='))) { this._overlayDisposer?.(); @@ -174,12 +188,9 @@ export class SchemaCellField extends ObservableReactComponent, { x: 0, y: 0 }); } - this._content = targVal; + this._unrenderedContent = targVal; this._props.highlightCells?.(targVal); - if (this._props.func(targVal, true).length > this._props.func(prevVal, true).length) { - this.setContent(targVal); - setTimeout(() => this.restoreCursorPosition(cursorPos), 0); - } + if (this.shouldUpdate(prevVal, targVal)) {this.setContent(targVal, true)}; }; @action @@ -206,6 +217,18 @@ export class SchemaCellField extends ObservableReactComponent { + this.setContent(this._unrenderedContent); + const cursorPos = this.cursorPosition; + setTimeout(() => this.restoreCursorPosition(cursorPos), 0); + } + , 0); + break; + case 'u': // for some reason 'u' otherwise exits the editor + e.stopPropagation(); + break; case 'Shift': case 'Alt': case 'Meta': case 'Control': case ':': //prettier-ignore break; // eslint-disable-next-line no-fallthrough @@ -225,8 +248,8 @@ export class SchemaCellField extends ObservableReactComponent() { equationHighlightRef = (text: string) => { } - eqHighlightFunc = (text: string, raw: boolean) => { - const info = this.schemaView.findCellRefs(text, raw); - if (raw) return info; + eqHighlightFunc = (text: string) => { + const info = this.schemaView.findCellRefs(text); const cells: HTMLDivElement[] = []; info.forEach(info => {cells.push(this.schemaView.getCellElement(info[0], info[1]))}) return cells; diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 94fd9ec7d..ab384a487 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -63,7 +63,7 @@ export interface SchemaTableCellProps { isolatedSelection: [boolean, boolean]; highlightCells: (text: string) => void; equationHighlightRef: ObservableMap; - func: (text: string, raw: boolean) => HTMLDivElement[] | []; + func: (text: string) => HTMLDivElement[] | []; } @@ -184,7 +184,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} contents={undefined} -- cgit v1.2.3-70-g09d2 From 9fab1b3ac096138fba3a99a2515ec44b526a3956 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 23 Jun 2024 02:54:24 -0400 Subject: text highlight works with 'this.' format --- src/client/views/collections/collectionSchema/SchemaCellField.tsx | 7 +++++-- src/client/views/collections/collectionSchema/SchemaRowBox.tsx | 2 ++ src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index fc191014c..aa6c382ef 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -53,7 +53,7 @@ export class SchemaCellField extends ObservableReactComponent { - // const refToUse = docRef === 'this' ? `${this.docIndex}` : docRef; + const adjMatch = match.replace('this.', `d${this.docIndex}`) chunkedText = chunkedText.replace(match, `${match}`); ++matchNum; }) diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index f4320dc09..45f178815 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -22,6 +22,7 @@ import { ContextMenu } from '../../ContextMenu'; import { CollectionFreeFormView } from '../collectionFreeForm'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; +import { infoState } from '../collectionFreeForm/CollectionFreeFormInfoState'; interface SchemaRowBoxProps extends FieldViewProps { rowIndex: number; @@ -129,6 +130,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { const info = this.schemaView.findCellRefs(text); const cells: HTMLDivElement[] = []; info.forEach(info => {cells.push(this.schemaView.getCellElement(info[0], info[1]))}) + console.log('info: ' + info + ' cells: ' + cells); return cells; }; render() { diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index ab384a487..6ccada48c 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -144,10 +144,10 @@ export class SchemaTableCell extends ObservableReactComponent { + adjustSelfReference = (field: string) => { const pattern = /\bthis.\b/g; const modField = field.replace(pattern, `d${this.docIndex}.`); - this._props.highlightCells(modField); + return modField; } // parses a field from the "idToDoc(####)" format to DocumentId (d#) format for readability @@ -183,8 +183,8 @@ export class SchemaTableCell extends ObservableReactComponent this._props.highlightCells(this.adjustSelfReference(text))} + getCells={(text: string) => this._props.func(this.adjustSelfReference(text))} ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} contents={undefined} -- cgit v1.2.3-70-g09d2 From b2691d6119dfa1f192ac6eb19650f44742b253f5 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 23 Jun 2024 03:36:21 -0400 Subject: col filling (really external setting of cell fieldval) works properly (reaction); moved 'remove doc' option to bottom of row menu --- .../collectionSchema/CollectionSchemaView.tsx | 6 +++--- .../collections/collectionSchema/SchemaCellField.tsx | 17 +++++++++++------ .../views/collections/collectionSchema/SchemaRowBox.tsx | 13 ++++++------- .../collections/collectionSchema/SchemaTableCell.tsx | 4 +--- 4 files changed, 21 insertions(+), 19 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 9c4eda3b8..2a84efa7c 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -829,9 +829,9 @@ export class CollectionSchemaView extends CollectionSubView() { this.closeColumnMenu(); }; - setCellValues = (key: string, value: string) => { - if (this._selectedCells.length === 1) this.docs.forEach(doc => !doc._lockedSchemaEditing &&Doc.SetField(doc, key, value)); // if only one cell selected, fill all - else this._selectedCells.forEach(doc => !doc._lockedSchemaEditing && Doc.SetField(doc, key, value)); // else only fill selected cells + setColumnValues = (key: string, value: string) => { + if (this._selectedCells.length === 1) this.docs.forEach(doc => !doc._lockedSchemaEditing &&Doc.SetField(doc, key, value)); + else this._selectedCells.forEach(doc => !doc._lockedSchemaEditing && Doc.SetField(doc, key, value)); return true; }; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index aa6c382ef..e85bf75e6 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -36,7 +36,7 @@ export class SchemaCellField extends ObservableReactComponent { this._unrenderedContent = this._props.GetValue() ?? ''; - this.setContent(this._unrenderedContent, true); + this.setContent(this._unrenderedContent); }, 0); //must be moved to end of batch or else other docs aren't loaded, so render as d-1 in function } @@ -65,6 +65,13 @@ export class SchemaCellField extends ObservableReactComponent this._props.GetValue(), + fieldVal => { + this._unrenderedContent = fieldVal ?? ''; + this.setContent(this._unrenderedContent); + } + ) } componentDidUpdate(prevProps: Readonly) { @@ -79,7 +86,7 @@ export class SchemaCellField extends ObservableReactComponent disposer?.()); this.finalizeEdit(false, true, false); } @@ -98,15 +105,12 @@ export class SchemaCellField extends ObservableReactComponent { const adjMatch = match.replace('this.', `d${this.docIndex}`) @@ -237,6 +241,8 @@ export class SchemaCellField extends ObservableReactComponent() { openContextMenu = (x: number, y: number) => { ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ - description: `Close doc`, - event: () => this.schemaView.removeDoc(this.Document), - icon: 'minus', - }); ContextMenu.Instance.addItem({ description: this.Document._lockedSchemaEditing ? 'Unlock field editing' : 'Lock field editing', event: () => this.Document._lockedSchemaEditing = !this.Document._lockedSchemaEditing, @@ -75,6 +70,11 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { event: () => this._props.addDocTab(this.Document, OpenWhere.addRight), icon: 'magnifying-glass', }); + ContextMenu.Instance.addItem({ + description: `Close doc`, + event: () => this.schemaView.removeDoc(this.Document), + icon: 'minus', + }); const childDocs = DocListCast(this.Document[Doc.LayoutFieldKey(this.Document)]) if (this.Document.type === 'collection' && childDocs.length) { ContextMenu.Instance.addItem({ @@ -119,7 +119,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { selectCell = (doc: Doc, col: number, shift: boolean, ctrl: boolean) => this.schemaView?.selectCell(doc, col, shift, ctrl); deselectCell = () => this.schemaView?.deselectAllCells(); selectedCells = () => this.schemaView?._selectedDocs; - setColumnValues = (field: any, value: any) => this.schemaView?.setCellValues(field, value) ?? false; + setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); highlightCells = (text: string) => this.schemaView?.highlightCells(text); @@ -130,7 +130,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { const info = this.schemaView.findCellRefs(text); const cells: HTMLDivElement[] = []; info.forEach(info => {cells.push(this.schemaView.getCellElement(info[0], info[1]))}) - console.log('info: ' + info + ' cells: ' + cells); return cells; }; render() { diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 6ccada48c..aa8401502 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -145,14 +145,12 @@ export class SchemaTableCell extends ObservableReactComponent { - const pattern = /\bthis.\b/g; - const modField = field.replace(pattern, `d${this.docIndex}.`); + const modField = field.replace(/\bthis.\b/g, `d${this.docIndex}.`); return modField; } // parses a field from the "idToDoc(####)" format to DocumentId (d#) format for readability cleanupField = (field: string) => { - if (field === ':=d6.type + d4.type + d3.type') console.log(true) const idPattern = /idToDoc\((.*?)\)/g; let modField = field.slice(); let matches; -- cgit v1.2.3-70-g09d2 From 6a3d0cc899020710d5b9aabe164649c686467024 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 25 Jun 2024 01:14:06 -0400 Subject: progress on refSelect (single click to add cell to equation) --- .../collectionSchema/CollectionSchemaView.tsx | 135 +++++++++++---------- .../collectionSchema/SchemaCellField.tsx | 25 ++-- .../collections/collectionSchema/SchemaRowBox.tsx | 8 +- .../collectionSchema/SchemaTableCell.tsx | 11 +- 4 files changed, 106 insertions(+), 73 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 48c34c647..c3dc4bad6 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -42,6 +42,7 @@ import { truncate } from 'lodash'; import { DocumentManager } from '../../../util/DocumentManager'; import { TbHemispherePlus } from 'react-icons/tb'; import { docs_v1 } from 'googleapis'; +import { SchemaCellField } from './SchemaCellField'; const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore @@ -104,7 +105,7 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _highlightedCellsInfo: Array<[doc: Doc, field: string]> = []; @observable _cellHighlightColors: ObservableMap = new ObservableMap(); @observable _docs: Doc[] = []; - @observable _inCellSelectMode: boolean = false; + @observable _referenceSelectMode = {enabled: false, currEditing: undefined} // target HTMLelement portal for showing a popup menu to edit cell values. public get MenuTarget() { @@ -113,7 +114,7 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get _selectedDocs() { // get all selected documents then filter out any whose parent is not this schema document - const selected = DocumentView.SelectedDocs().filter(doc => this.docs.includes(doc)); + const selected = DocumentView.SelectedDocs().filter(doc => this.docs.includes(doc) && this._selectedCells.includes(doc)); if (!selected.length) { // if no schema doc is directly selected, test if a child of a schema doc is selected (such as in the preview window) const childOfSchemaDoc = DocumentView.SelectedDocs().find(sel => DocumentView.getContextPath(sel, true).includes(this.Document)); @@ -651,7 +652,19 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { + selectCell = (doc: Doc | undefined, col: number, shiftKey: boolean, ctrlKey: boolean) => { + if (!doc) return; + + if (this._referenceSelectMode.enabled) { + const docIndex = DocumentView.getDocViewIndex(doc); + const field = this.columnKeys[col]; + const refToAdd = `d${docIndex}.${field}` + const editedField = this._referenceSelectMode.currEditing ? this._referenceSelectMode.currEditing as SchemaCellField : null; + editedField?.appendText(refToAdd); + editedField?.setupRefSelect(false); + return; + } + this.closeColumnMenu(); if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); @@ -1015,64 +1028,64 @@ export class CollectionSchemaView extends CollectionSubView() { this._filterSearchValue = e.target.value; }; - @computed get newFieldMenu() { - return ( -
-
- { - this._newFieldType = ColumnType.Number; - this._newFieldDefault = 0; - })} - /> - number -
-
- { - this._newFieldType = ColumnType.Boolean; - this._newFieldDefault = false; - })} - /> - boolean -
-
- { - this._newFieldType = ColumnType.String; - this._newFieldDefault = ''; - })} - /> - string -
-
value: {this.fieldDefaultInput}
-
{this._newFieldWarning}
-
{ - if (this.documentKeys.includes(this._menuValue)) { - this._newFieldWarning = 'Field already exists'; - } else if (this._menuValue.length === 0) { - this._newFieldWarning = 'Field cannot be an empty string'; - } else { - this.setKey(this._menuValue, this._newFieldDefault); - } - this._columnMenuIndex = undefined; - })}> - done -
-
- ); - } + // @computed get newFieldMenu() { + // return ( + //
+ //
+ // { + // this._newFieldType = ColumnType.Number; + // this._newFieldDefault = 0; + // })} + // /> + // number + //
+ //
+ // { + // this._newFieldType = ColumnType.Boolean; + // this._newFieldDefault = false; + // })} + // /> + // boolean + //
+ //
+ // { + // this._newFieldType = ColumnType.String; + // this._newFieldDefault = ''; + // })} + // /> + // string + //
+ //
value: {this.fieldDefaultInput}
+ //
{this._newFieldWarning}
+ //
{ + // if (this.documentKeys.includes(this._menuValue)) { + // this._newFieldWarning = 'Field already exists'; + // } else if (this._menuValue.length === 0) { + // this._newFieldWarning = 'Field cannot be an empty string'; + // } else { + // this.setKey(this._menuValue, this._newFieldDefault); + // } + // this._columnMenuIndex = undefined; + // })}> + // done + //
+ //
+ // ); + // } onKeysPassiveWheel = (e: WheelEvent) => { // if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this) diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index e13763b45..ea46fb432 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -15,6 +15,8 @@ export interface SchemaCellFieldProps { editing?: boolean; oneLine?: boolean; Document: Doc; + fieldKey: string; + refSelectModeInfo: {enabled: boolean, currEditing: SchemaCellField | undefined}; highlightCells?: (text: string) => void; GetValue(): string | undefined; SetValue(value: string, shiftDown?: boolean, enterKey?: boolean): boolean; @@ -41,10 +43,6 @@ export class SchemaCellField extends ObservableReactComponent { - console.log('content: ' + content) this._displayedContent = this.makeSpans(content); if (restoreCursorPos) { const cursorPos = this.cursorPosition; @@ -135,6 +133,12 @@ export class SchemaCellField extends ObservableReactComponent { + this._unrenderedContent += text; + this.setContent(this._unrenderedContent); + } + @action setIsFocused = (value: boolean) => { const wasFocused = this._editing; @@ -209,6 +213,12 @@ export class SchemaCellField extends ObservableReactComponent { + const properties = this._props.refSelectModeInfo; + properties.enabled = enabled; + properties.currEditing = enabled ? this : undefined; + } + @action onKeyDown = (e: React.KeyboardEvent) => { if (e.nativeEvent.defaultPrevented) return; // hack .. DashFieldView grabs native events, but react ignores stoppedPropagation and preventDefault, so we need to check it here @@ -234,7 +244,7 @@ export class SchemaCellField extends ObservableReactComponent() { return '' } + @computed get refSelectModeInfo() { + return this.schemaView._referenceSelectMode; + } + @computed get menuInfos() { const infos: Array = []; if (this.Document._lockedSchemaEditing) infos.push('lock'); @@ -123,9 +127,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); highlightCells = (text: string) => this.schemaView?.highlightCells(text); - equationHighlightRef = (text: string) => { - - } eqHighlightFunc = (text: string) => { const info = this.schemaView.findCellRefs(text); const cells: HTMLDivElement[] = []; @@ -174,6 +175,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() {
{this.schemaView?.columnKeys?.map((key, index) => ( void; equationHighlightRef: ObservableMap; func: (text: string) => HTMLDivElement[] | []; - + refSelectModeInfo: {enabled: boolean, currEditing: SchemaCellField | undefined}; } function selectedCell(props: SchemaTableCellProps) { @@ -78,7 +78,7 @@ function selectedCell(props: SchemaTableCellProps) { @observer export class SchemaTableCell extends ObservableReactComponent { - @observable _highlighted: boolean = false; + // private _fieldRef: SchemaCellField | null = null; constructor(props: SchemaTableCellProps) { super(props); @@ -143,6 +143,11 @@ export class SchemaTableCell extends ObservableReactComponent { + // this._fieldRef?.appendText(text); + // } adjustSelfReference = (field: string) => { const modField = field.replace(/\bthis.\b/g, `d${this.docIndex}.`); @@ -180,6 +185,8 @@ export class SchemaTableCell extends ObservableReactComponent this._props.highlightCells(this.adjustSelfReference(text))} getCells={(text: string) => this._props.func(this.adjustSelfReference(text))} -- cgit v1.2.3-70-g09d2 From 54559c677ac3a91e72680b5b7c889d63439edf58 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:10:05 -0400 Subject: focus is no longer lost --- src/client/util/SelectionManager.ts | 1 + .../collectionSchema/CollectionSchemaView.tsx | 26 ++++++++++++---------- .../collectionSchema/SchemaCellField.tsx | 11 ++++----- .../collections/collectionSchema/SchemaRowBox.tsx | 3 +++ .../collectionSchema/SchemaTableCell.tsx | 8 +++++++ 5 files changed, 32 insertions(+), 17 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 0b942116c..fc494583f 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -58,6 +58,7 @@ export class SelectionManager { }); public static DeselectAll = (except?: Doc): void => { + const found = this.Instance.SelectedViews.find(dv => dv.Document === except); runInAction(() => { if (LinkManager.Instance) { diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index c3dc4bad6..3b5a32ca7 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -634,6 +634,7 @@ export class CollectionSchemaView extends CollectionSubView() { @action clearSelection = () => { + if (this._referenceSelectMode.enabled) return; DocumentView.DeselectAll(); this.deselectAllCells(); }; @@ -651,20 +652,19 @@ export class CollectionSchemaView extends CollectionSubView() { } }; - @action - selectCell = (doc: Doc | undefined, col: number, shiftKey: boolean, ctrlKey: boolean) => { + selectReference = (doc: Doc | undefined, col: number) => { if (!doc) return; + const docIndex = DocumentView.getDocViewIndex(doc); + const field = this.columnKeys[col]; + const refToAdd = `d${docIndex}.${field}` + const editedField = this._referenceSelectMode.currEditing ? this._referenceSelectMode.currEditing as SchemaCellField : null; + editedField?.appendText(refToAdd); + editedField?.setupRefSelect(false); + return; + } - if (this._referenceSelectMode.enabled) { - const docIndex = DocumentView.getDocViewIndex(doc); - const field = this.columnKeys[col]; - const refToAdd = `d${docIndex}.${field}` - const editedField = this._referenceSelectMode.currEditing ? this._referenceSelectMode.currEditing as SchemaCellField : null; - editedField?.appendText(refToAdd); - editedField?.setupRefSelect(false); - return; - } - + @action + selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { this.closeColumnMenu(); if (!shiftKey && !ctrlKey) this.clearSelection(); !this._selectedCells && (this._selectedCells = []); @@ -687,12 +687,14 @@ export class CollectionSchemaView extends CollectionSubView() { @action deselectCell = (doc: Doc) => { + console.log('single deselect called') this._selectedCells && (this._selectedCells = this._selectedCells.filter(d => d !== doc)); if (this.rowIndex(doc) === this._lowestSelectedIndex) this._lowestSelectedIndex = Math.min(...this._selectedDocs.map(d => this.rowIndex(d))); }; @action deselectAllCells = () => { + console.log('deselectall called') this._selectedCells = []; this._lowestSelectedIndex = -1; }; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 84b4d3462..06d3926a8 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -62,6 +62,7 @@ export class SchemaCellField extends ObservableReactComponent this._editing, editing => { if (editing) { + if (this.lastChar !== '+') this.setupRefSelect(false); setTimeout(() => { if (this._inputref?.innerText.startsWith('=') || this._inputref?.innerText.startsWith(':=')) { this._overlayDisposer?.(); @@ -145,8 +146,8 @@ export class SchemaCellField extends ObservableReactComponent { - this._unrenderedContent += text; - this.setContent(this._unrenderedContent); + const newText = this._unrenderedContent.concat(text); + this.onChange(undefined, newText); } @action @@ -209,9 +210,9 @@ export class SchemaCellField extends ObservableReactComponent) => { + onChange = (e: FormEvent | undefined, newText?: string) => { const prevVal = this._unrenderedContent; - const targVal = e.currentTarget.innerText; + const targVal = newText ?? e!.currentTarget.innerText; // TODO: bang if (!(targVal.startsWith(':=') || targVal.startsWith('='))) { this._overlayDisposer?.(); this._overlayDisposer = undefined; @@ -319,7 +320,7 @@ export class SchemaCellField extends ObservableReactComponent { this._inputref = r; }} style={{ cursor: 'text', outline: 'none', overflow: 'auto', minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, }} - onBlur={e => this.finalizeEdit(false, true, false)} + onBlur={e => {this._props.refSelectModeInfo.enabled ? setTimeout(() => {this.setIsFocused(true)}, 1000) : this.finalizeEdit(false, true, false)}} autoFocus onInput={this.onChange} onKeyDown={this.onKeyDown} diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index b15804d41..3f5c2a90e 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -23,6 +23,7 @@ import { CollectionFreeFormView } from '../collectionFreeForm'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { infoState } from '../collectionFreeForm/CollectionFreeFormInfoState'; +import { TbShieldX } from 'react-icons/tb'; interface SchemaRowBoxProps extends FieldViewProps { rowIndex: number; @@ -127,6 +128,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); highlightCells = (text: string) => this.schemaView?.highlightCells(text); + selectReference = (doc: Doc, col: number) => {this.schemaView.selectReference(doc, col)} eqHighlightFunc = (text: string) => { const info = this.schemaView.findCellRefs(text); const cells: HTMLDivElement[] = []; @@ -175,6 +177,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() {
{this.schemaView?.columnKeys?.map((key, index) => ( ; func: (text: string) => HTMLDivElement[] | []; refSelectModeInfo: {enabled: boolean, currEditing: SchemaCellField | undefined}; + selectReference: (doc: Doc, col: number) => void; } function selectedCell(props: SchemaTableCellProps) { @@ -254,6 +255,13 @@ export class SchemaTableCell extends ObservableReactComponent StopEvent(e)} onPointerDown={action(e => { + if (this._props.refSelectModeInfo.enabled && !selectedCell(this._props)){ + e.stopPropagation(); + e.preventDefault(); + this._props.selectReference(this._props.Document, this._props.col); + return; + } + const shift: boolean = e.shiftKey; const ctrl: boolean = e.ctrlKey; if (this._props.isRowActive?.()) { -- cgit v1.2.3-70-g09d2 From 2437028db1f273350b0422da0ef3a5f520ffce59 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:48:25 -0400 Subject: self-reference warning added --- src/client/views/collections/collectionSchema/SchemaCellField.tsx | 6 +++++- src/client/views/collections/collectionSchema/SchemaRowBox.tsx | 2 +- src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 8e751f4ba..27ca37c2b 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -33,6 +33,7 @@ export class SchemaCellField extends ObservableReactComponent() { void; equationHighlightRef: ObservableMap; - func: (text: string) => HTMLDivElement[] | []; + eqHighlightFunc: (text: string) => HTMLDivElement[] | []; refSelectModeInfo: {enabled: boolean, currEditing: SchemaCellField | undefined}; selectReference: (doc: Doc, col: number) => void; } @@ -190,7 +190,7 @@ export class SchemaTableCell extends ObservableReactComponent this._props.highlightCells(this.adjustSelfReference(text))} - getCells={(text: string) => this._props.func(this.adjustSelfReference(text))} + getCells={(text: string) => this._props.eqHighlightFunc(this.adjustSelfReference(text))} ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} contents={undefined} -- cgit v1.2.3-70-g09d2 From 8ceaba8b8264f5519de732cc603dcd276b4b4f4d Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Fri, 28 Jun 2024 01:49:10 -0400 Subject: header text no longer shifts left on hover --- src/client/documents/Documents.ts | 6 +++++ src/client/util/Scripting.ts | 9 ++++++-- .../collectionSchema/CollectionSchemaView.scss | 1 - .../collectionSchema/SchemaCellField.tsx | 4 +++- .../collectionSchema/SchemaColumnHeader.tsx | 6 ++--- .../collections/collectionSchema/SchemaRowBox.tsx | 6 +---- .../collectionSchema/SchemaTableCell.tsx | 26 +++++++++++++++++----- src/client/views/nodes/FieldView.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 2 +- 9 files changed, 43 insertions(+), 19 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index dabbf9591..1b1608cd5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -143,7 +143,12 @@ class ListInfo extends FInfo { fieldType? = FInfoFieldType.list; values?: List[] = []; } +class MapInfo extends FInfo { + fieldType? = FInfoFieldType.list; + values?: List[] = []; +} type BOOLt = BoolInfo | boolean; +type MAPt = MapInfo | Map; type NUMt = NumInfo | number; type STRt = StrInfo | string; type LISTt = ListInfo | List; @@ -229,6 +234,7 @@ export class DocumentOptions { _lockedTransform?: BOOLt = new BoolInfo('lock the freeform_panx,freeform_pany and scale parameters of the document so that it be panned/zoomed'); _childrenSharedWithSchema?: BOOLt = new BoolInfo("whether this document's children are displayed in its parent schema view", false); _lockedSchemaEditing?: BOOLt = new BoolInfo("", false); + _schemaInputs?: LISTt = new ListInfo('user inputs to schema field', false) dataViz_title?: string; dataViz_line?: string; diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index 6ef592ef2..c7aa56c1e 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -183,14 +183,19 @@ function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, inde ); } +ScriptField.CompileScript(value, {}, true, undefined, DocumentIconContainer.getTransformer()); +//addreturn = true +//capturedvariables = undefined +// + export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult { - const captured = options.capturedVariables ?? {}; + const captured = options.capturedVariables ?? {}; const signature = Object.keys(captured).reduce((p, v) => { const formatCapture = (obj: any) => `${v}=${obj instanceof RefField ? 'XXX' : obj.toString()}`; if (captured[v] instanceof Array) return p + (captured[v] as any).map(formatCapture); return p + formatCapture(captured[v]); }, ''); - const found = ScriptField.GetScriptFieldCache(script + ':' + signature); + const found = ScriptField.GetScriptFieldCache(script + ':' + signature); // if already compiled, found is the result; cache set below if (found) return found as CompiledScript; const { requiredType = '', addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options; if (options.params && !options.params.this) options.params.this = Doc.name; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 6b53eb1cc..425b67fa9 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -155,7 +155,6 @@ padding: 0; z-index: 1; border: 1px solid $medium-gray; - //overflow: hidden; .schema-column-title { flex-grow: 2; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 27ca37c2b..c7c483df8 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -321,11 +321,13 @@ export class SchemaCellField extends ObservableReactComponent + staticDisplay = () => { return { // eslint-disable-next-line react/jsx-props-no-spreading - this._props.fieldContents ? : this.props.contents ? this._props.contents?.valueOf() : '' + this._props.fieldContents ? : '' } } diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index d16cde1f8..83a136737 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -237,11 +237,11 @@ export class SchemaColumnHeader extends ObservableReactComponent
this._props.resizeColumn(e, this._props.columnIndex)} /> -
{this.editableView}
+
{this.editableView}
-
- {this.displayButton ? this.headerButton : null} +
+ {this.headerButton}
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index c9feeac6b..077d95c57 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -97,10 +97,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { return '' } - @computed get refSelectModeInfo() { - return this.schemaView._referenceSelectMode; - } - @computed get menuInfos() { const infos: Array = []; if (this.Document._lockedSchemaEditing) infos.push('lock'); @@ -178,7 +174,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { {this.schemaView?.columnKeys?.map((key, index) => ( { // private _fieldRef: SchemaCellField | null = null; + private _submittedValue: string = ''; constructor(props: SchemaTableCellProps) { super(props); @@ -157,19 +159,31 @@ export class SchemaTableCell extends ObservableReactComponent { - const idPattern = /idToDoc\((.*?)\)/g; let modField = field.slice(); + let eqSymbol: string = ''; + if (modField.startsWith('=')) {modField = modField.substring(1); eqSymbol += '=';} + if (modField.startsWith(':=')) {modField = modField.substring(2); eqSymbol += ':=';} + + const idPattern = /idToDoc\((.*?)\)/g; let matches; let results = new Array<[id: string, func: string]>(); while ((matches = idPattern.exec(field)) !== null) {results.push([matches[0], matches[1].replace(/"/g, '')]); } results.forEach((idFuncPair) => {modField = modField.replace(idFuncPair[0], 'd' + (DocumentView.getDocViewIndex(IdToDoc(idFuncPair[1]))).toString());}) - if (modField.charAt(modField.length - 1) === ';') modField = modField.substring(0, modField.length - 1); + + for (let i = 0; i < modField.length; ++i){ + + } + + if (modField.endsWith(';')) modField = modField.substring(0, modField.length - 1); + + const inQuotes = (field: string) => {return ((field.startsWith('`') && field.endsWith('`')) || (field.startsWith("'") && field.endsWith("'")) || (field.startsWith('"') && field.endsWith('"')))} + if (!inQuotes(this._submittedValue) && inQuotes(modField)) modField = modField.substring(1, modField.length - 1); const selfRefPattern = `d${this.docIndex}.${this._props.fieldKey}` const selfRefRegX = RegExp(selfRefPattern, 'g'); if (selfRefRegX.exec(modField) !== null) { return 'Invalid'} - return modField; + return eqSymbol + modField; } @computed get defaultCellContent() { @@ -196,7 +210,8 @@ export class SchemaTableCell extends ObservableReactComponent this.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} + ////const script = ScriptCast(fieldProps.Document[this._props.fieldKey]).rawscript; + GetValue={() => ScriptCast(fieldProps.Document[this._props.fieldKey])?.rawscript ?? ''} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); @@ -205,6 +220,7 @@ export class SchemaTableCell extends ObservableReactComponent { const field = this.fieldval; // prettier-ignore if (field instanceof Doc) return

{field.title?.toString()}

; - if (field === undefined) return

{''}

; + if (field === undefined) return

{''}

; if (field instanceof DateField) return

{field.date.toLocaleString()}

; if (field instanceof List) return
{field.map(f => Field.toString(f)).join(', ')}
; if (field instanceof WebField) return

{Field.toString(field.url.href)}

; diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 66e210c03..bc6633f23 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -88,7 +88,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { const type: 'computed' | 'script' | false = rawvalue.startsWith(':=') ? 'computed' : rawvalue.startsWith('$=') ? 'script' : false; rawvalue = type ? rawvalue.substring(2) : rawvalue; rawvalue = rawvalue.replace(/.*\(\((.*)\)\)/, 'dashCallChat(_setCacheResult_, this, `$1`)'); - const value = ["'", '"', '`'].includes(rawvalue.length ? rawvalue[0] : '') || !isNaN(rawvalue as any) ? rawvalue : '`' + rawvalue + '`'; + const value = (["'", '"', '`'].includes(rawvalue.length ? rawvalue[0] : '') || !isNaN(rawvalue as any)) ? rawvalue : '`' + rawvalue + '`'; let script = ScriptField.CompileScript(rawvalue, {}, true, undefined, DocumentIconContainer.getTransformer()); if (!script.compiled) { -- cgit v1.2.3-70-g09d2 From 21a9278abe3bab3a7da7eef079a27169cc2cd49c Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:24:40 -0400 Subject: col drag stutter fixed --- src/client/util/Scripting.ts | 8 +-- .../collectionSchema/CollectionSchemaView.tsx | 70 ++++++++++++++-------- .../collectionSchema/SchemaColumnHeader.tsx | 2 + .../collectionSchema/SchemaTableCell.tsx | 6 +- 4 files changed, 52 insertions(+), 34 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index c7aa56c1e..5202e62a3 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -183,10 +183,10 @@ function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, inde ); } -ScriptField.CompileScript(value, {}, true, undefined, DocumentIconContainer.getTransformer()); -//addreturn = true -//capturedvariables = undefined -// +// ScriptField.CompileScript(value, {}, true, undefined, DocumentIconContainer.getTransformer()); +// //addreturn = true +// //capturedvariables = undefined +// // export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult { const captured = options.capturedVariables ?? {}; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 497c781fd..93347f067 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -95,7 +95,7 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _filterSearchValue: string = ''; @observable _selectedCol: number = 0; @observable _selectedCells: Array = []; - @observable _mouseCoordinates = { x: 0, y: 0 }; + @observable _mouseCoordinates = { x: 0, y: 0, prevX: 0, prevY: 0 }; @observable _lowestSelectedIndex: number = -1; //lowest index among selected rows; used to properly sync dragged docs with cursor position @observable _relCursorIndex: number = -1; //cursor index relative to the current selected cells @observable _draggedColIndex: number = 0; @@ -413,7 +413,7 @@ export class CollectionSchemaView extends CollectionSubView() { dragColumn = (e: PointerEvent, index: number) => { this.closeColumnMenu(); this._draggedColIndex = index; - this._colBeingDragged = true; + this.setColDrag(true); const dragData = new DragManager.ColumnDragData(index); const dragEles = [this._colEles[index]]; this.childDocs.forEach(doc => dragEles.push(this._rowEles.get(doc).children[1].children[index])); @@ -499,6 +499,26 @@ export class CollectionSchemaView extends CollectionSubView() { }); }); + removeDragHighlight = () => { + this._colEles.forEach((colRef, i) => { + const sorted = i === this.columnKeys.indexOf(this.sortField); + if (sorted) return; + + colRef.style.borderLeft = ''; + colRef.style.borderRight = ''; + colRef.style.borderTop = ''; + + this.childDocs.forEach(doc => { + const cell = this._rowEles.get(doc).children[1].children[i]; + if (!(this._selectedDocs.includes(doc) && i === this._selectedCol) && !(this.highlightedCells.includes(cell))) { + cell.style.borderLeft = ''; + cell.style.borderRight = ''; + cell.style.borderBottom = ''; + } + }); + }); + } + highlightSortedColumn = (field?: string, descending?: boolean) => { let index = -1; let highlightColors: string[] = []; @@ -703,28 +723,11 @@ export class CollectionSchemaView extends CollectionSubView() { return this.findRowDropIndex(mouseY); } + @action onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.columnDragData) { - this._colBeingDragged = false; + this.setColDrag(false); e.stopPropagation(); - - this._colEles.forEach((colRef, i) => { - const sorted = i === this.columnKeys.indexOf(this.sortField); - if (sorted) return; - - colRef.style.borderLeft = ''; - colRef.style.borderRight = ''; - colRef.style.borderTop = ''; - - this.childDocs.forEach(doc => { - const cell = this._rowEles.get(doc).children[1].children[i]; - if (!(this._selectedDocs.includes(doc) && i === this._selectedCol) && !(this.highlightedCells.includes(cell))) { - cell.style.borderLeft = ''; - cell.style.borderRight = ''; - cell.style.borderBottom = ''; - } - }); - }); return true; } @@ -1196,18 +1199,33 @@ export class CollectionSchemaView extends CollectionSubView() { ); } + @action setColDrag = (beingDragged: boolean) => { + this._colBeingDragged = beingDragged; + !beingDragged && this.removeDragHighlight(); + } + + @action updateMouseCoordinates = (e: React.PointerEvent) => { + const prevX = this._mouseCoordinates.x; + const prevY = this._mouseCoordinates.y; + this._mouseCoordinates = { x: e.clientX, y: e.clientY, prevX: prevX, prevY: prevY }; + } + @action onPointerMove = (e: React.PointerEvent) => { if (DragManager.docsBeingDragged.length) { - this._mouseCoordinates = { x: e.clientX, y: e.clientY }; + this.updateMouseCoordinates(e); } if (this._colBeingDragged) { + this.updateMouseCoordinates(e); const newIndex = this.findColDropIndex(e.clientX); - if (newIndex !== this._draggedColIndex) this.moveColumn(this._draggedColIndex, newIndex ?? this._draggedColIndex); - this._draggedColIndex = newIndex || this._draggedColIndex; + const direction: number = this._mouseCoordinates.x > this._mouseCoordinates.prevX ? 1 : 0; + if (newIndex !== undefined && ((newIndex > this._draggedColIndex && direction === 1) || (newIndex < this._draggedColIndex && direction === 0))) { + this.moveColumn(this._draggedColIndex, newIndex ?? this._draggedColIndex); + this._draggedColIndex = newIndex !== undefined ? newIndex : this._draggedColIndex; + } this.highlightSortedColumn(); //TODO: Make this more efficient this.restoreCellHighlights(); - !(this.sortField && this._draggedColIndex === this.columnKeys.indexOf(this.sortField)) && this.highlightDraggedColumn(newIndex ?? this._draggedColIndex); + !(this.sortField && this._draggedColIndex === this.columnKeys.indexOf(this.sortField)) && this.highlightDraggedColumn(this._draggedColIndex); } }; @@ -1286,7 +1304,7 @@ export class CollectionSchemaView extends CollectionSubView() {
this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)} onPointerMove={e => this.onPointerMove(e)} - onPointerDown={() => this.closeColumnMenu()}> + onPointerDown={() => {this.closeColumnMenu(); this.setColDrag(false)}}>
+ +
this._props.resizeColumn(e, this._props.columnIndex)} />
); } diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index c0e1743a5..d06e2a147 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -16,7 +16,7 @@ import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field, IdToDoc } from '../../../../fields/Doc'; import { RichTextField } from '../../../../fields/RichTextField'; import { ColumnType } from '../../../../fields/SchemaHeaderField'; -import { BoolCast, Cast, DateCast, DocCast, FieldValue, ScriptCast, StrCast, toList } from '../../../../fields/Types'; +import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast, toList } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { FInfo, FInfoFieldType } from '../../../documents/Documents'; import { dropActionType } from '../../../util/DropActionTypes'; @@ -35,7 +35,6 @@ import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { ContextMenu } from '../../ContextMenu'; import { SchemaCellField } from './SchemaCellField'; -import { ComputedField } from '../../../../fields/ScriptField'; export interface SchemaTableCellProps { Document: Doc; @@ -210,8 +209,7 @@ export class SchemaTableCell extends ObservableReactComponent ScriptCast(fieldProps.Document[this._props.fieldKey])?.rawscript ?? ''} + GetValue={() => this.cleanupField(Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey))} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); -- cgit v1.2.3-70-g09d2 From b01f8732034396114c6a37665054de1617ccda1b Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:32:27 -0400 Subject: fixed selected row highlight on new col --- src/client/views/collections/collectionSchema/SchemaRowBox.tsx | 5 +---- src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 077d95c57..9ac7a24b2 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -90,10 +90,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { } @computed get menuBackgroundColor(){ - if (this.Document._lockedSchemaEditing){ - if (this._props.isSelected()) return '#B0D1E7' - else return '#F5F5F5' - } + if (this.Document._lockedSchemaEditing) {return '#F5F5F5'} return '' } diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index d06e2a147..084306c4a 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -94,10 +94,7 @@ export class SchemaTableCell extends ObservableReactComponent Date: Sat, 29 Jun 2024 19:07:27 -0400 Subject: highlight updates properly when highlighted cell is selected; no longer possible to add EmptyKey to equation --- .../collections/collectionSchema/CollectionSchemaView.tsx | 13 +++++++------ .../views/collections/collectionSchema/SchemaTableCell.tsx | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index d3259d42e..bcb94e10d 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -73,11 +73,8 @@ export class CollectionSchemaView extends CollectionSubView() { constructor(props: any) { super(props); makeObservable(this); - const lightenedColor = (r: number, g: number, b:number) => { - const lightened = ClientUtils.lightenRGB(r, g, b, 165); - return {r: lightened[0], g: lightened[1], b: lightened[2]} - } - const colors = (r: number, g: number, b: number): [any, any] => {return [{r: r, g: g, b: b}, lightenedColor(r, g, b)]} + const lightenedColor = (r: number, g: number, b:number) => { const lightened = ClientUtils.lightenRGB(r, g, b, 165); return {r: lightened[0], g: lightened[1], b: lightened[2]}} // prettier-ignore + const colors = (r: number, g: number, b: number): [any, any] => {return [{r: r, g: g, b: b}, lightenedColor(r, g, b)]} // prettier-ignore this._eqHighlightColors.push(colors(70, 150, 50)); this._eqHighlightColors.push(colors(180, 70, 20)); this._eqHighlightColors.push(colors(70, 50, 150)); @@ -602,7 +599,11 @@ export class CollectionSchemaView extends CollectionSubView() { } removeCellHighlights = () => { - this.highlightedCells.forEach(cell => {cell.style.border = ''; cell.style.backgroundColor = '';}); + this._highlightedCellsInfo.forEach(info => { + const doc = info[0]; + const cell = this.getCellElement(doc, info[1]); + if (!this._selectedDocs.includes(doc)) cell.style.border = ''; + cell.style.backgroundColor = '';}); this._highlightedCellsInfo = []; } diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 084306c4a..1f5684151 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -266,6 +266,8 @@ export class SchemaTableCell extends ObservableReactComponent StopEvent(e)} onPointerDown={action(e => { + if (this.lockedInteraction) { e.stopPropagation(); e.preventDefault(); return; } + if (this._props.refSelectModeInfo.enabled && !selectedCell(this._props)){ e.stopPropagation(); e.preventDefault(); -- cgit v1.2.3-70-g09d2 From 3dd0a92767972736f415341c0b6e06e6e3a242b1 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:38:24 -0400 Subject: highlighting then un-highlighting a selected cell with equations now properly maintains original select highlight --- src/client/views/EditableView.tsx | 1 - .../collectionSchema/CollectionSchemaView.tsx | 19 +++++++++++++++---- .../collections/collectionSchema/SchemaCellField.tsx | 8 ++++++-- .../collections/collectionSchema/SchemaRowBox.tsx | 13 ++----------- .../collections/collectionSchema/SchemaTableCell.tsx | 10 +++------- 5 files changed, 26 insertions(+), 25 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 0c09e12de..af6a43555 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -206,7 +206,6 @@ export class EditableView extends ObservableReactComponent { @action finalizeEdit(value: string, shiftDown: boolean, lostFocus: boolean, enterKey: boolean) { - //if (invalid) raise error if (this._props.SetValue(value, shiftDown, enterKey)) { this._editing = false; this._props.isEditingCallback?.(false); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 7a90b3505..b81cfa821 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -606,12 +606,24 @@ export class CollectionSchemaView extends CollectionSubView() { return cells; } + selectionOverlap = (doc: Doc): [boolean, boolean] => { + const docs = this.docsWithDrag.docs; + const index = this.rowIndex(doc); + const selectedBelow: boolean = this._selectedDocs.includes(docs[index + 1]); + const selectedAbove: boolean = this._selectedDocs.includes(docs[index - 1]); + return [selectedAbove, selectedBelow]; + } + removeCellHighlights = () => { this._highlightedCellsInfo.forEach(info => { const doc = info[0]; const field = info[1]; const cell = this.getCellElement(doc, field); - if (!(this._selectedDocs.includes(doc) && this._selectedCol === this.columnKeys.indexOf(field))) cell.style.border = ''; + if (this._selectedDocs.includes(doc) && this._selectedCol === this.columnKeys.indexOf(field)) { + cell.style.border = `solid 2px ${Colors.MEDIUM_BLUE}`; + if (this.selectionOverlap(doc)[0]) cell.style.borderTop = ''; + if (this.selectionOverlap(doc)[1]) cell.style.borderBottom = ''; + } else cell.style.border = ''; cell.style.backgroundColor = '';}); this._highlightedCellsInfo = []; } @@ -741,7 +753,6 @@ export class CollectionSchemaView extends CollectionSubView() { @action onInternalDrop = (e: Event, de: DragManager.DropEvent) => { - console.log('called') if (de.complete.columnDragData) { setTimeout(() => {this.setColDrag(false);}); e.stopPropagation(); @@ -881,8 +892,8 @@ export class CollectionSchemaView extends CollectionSubView() { this.closeColumnMenu(); }; - setColumnValues = (key: string, value: string) => { - if (this._selectedCells.length === 1) this.docs.forEach(doc => !doc._lockedSchemaEditing &&Doc.SetField(doc, key, value)); + setCellValues = (key: string, value: string) => { + if (this._selectedCells.length === 1) this.docs.forEach(doc => !doc._lockedSchemaEditing && Doc.SetField(doc, key, value)); else this._selectedCells.forEach(doc => !doc._lockedSchemaEditing && Doc.SetField(doc, key, value)); return true; }; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index c7c483df8..e1059b8fc 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -95,7 +95,7 @@ export class SchemaCellField extends ObservableReactComponent this._props.GetValue(), fieldVal => { this._unrenderedContent = fieldVal ?? ''; - this.setContent(this._unrenderedContent); + this.finalizeEdit(false, false, false); } ) } @@ -246,6 +246,10 @@ export class SchemaCellField extends ObservableReactComponent) => { 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(); @@ -302,7 +306,7 @@ export class SchemaCellField extends ObservableReactComponent() { return infos; } - @computed get isolatedSelection() { - const toReturn: [boolean, boolean] = [true, true]; - const docs = this.schemaView.docsWithDrag.docs; - const selectedBelow: boolean = this.schemaView?._selectedDocs.includes(docs[this.rowIndex + 1]); - const selectedAbove: boolean = this.schemaView?._selectedDocs.includes(docs[this.rowIndex - 1]); - toReturn[0] = selectedAbove; - toReturn[1] = selectedBelow; - return toReturn; - } - + isolatedSelection = (doc: Doc) => {return this.schemaView?.selectionOverlap(doc)}; setCursorIndex = (mouseY: number) => this.schemaView?.setRelCursorIndex(mouseY); 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?._selectedDocs; - setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false; + setColumnValues = (field: any, value: any) => this.schemaView?.setCellValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); computeRowIndex = () => this.schemaView?.rowIndex(this.Document); highlightCells = (text: string) => this.schemaView?.highlightCells(text); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 1f5684151..e2a05da7f 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -60,7 +60,7 @@ export interface SchemaTableCellProps { autoFocus?: boolean; // whether to set focus on creation, othwerise wait for a click rootSelected?: () => boolean; rowSelected: () => boolean; - isolatedSelection: [boolean, boolean]; + isolatedSelection: (doc: Doc) => [boolean, boolean]; highlightCells: (text: string) => void; equationHighlightRef: ObservableMap; eqHighlightFunc: (text: string) => HTMLDivElement[] | []; @@ -174,10 +174,6 @@ export class SchemaTableCell extends ObservableReactComponent {return ((field.startsWith('`') && field.endsWith('`')) || (field.startsWith("'") && field.endsWith("'")) || (field.startsWith('"') && field.endsWith('"')))} if (!inQuotes(this._submittedValue) && inQuotes(modField)) modField = modField.substring(1, modField.length - 1); - - const selfRefPattern = `d${this.docIndex}.${this._props.fieldKey}` - const selfRefRegX = RegExp(selfRefPattern, 'g'); - if (selfRefRegX.exec(modField) !== null) { return 'Invalid'} return eqSymbol + modField; } @@ -255,8 +251,8 @@ export class SchemaTableCell extends ObservableReactComponent = []; sides[0] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // left sides[1] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // right - sides[2] = (!this._props.isolatedSelection[0] && selectedCell(this._props)) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top - sides[3] = (!this._props.isolatedSelection[1] && selectedCell(this._props)) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom + sides[2] = (!this._props.isolatedSelection(this._props.Document)[0] && selectedCell(this._props)) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top + sides[3] = (!this._props.isolatedSelection(this._props.Document)[1] && selectedCell(this._props)) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom return sides; } -- cgit v1.2.3-70-g09d2 From 32771d4b202a8552815c7f4459d5ac5142401292 Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Wed, 3 Jul 2024 04:40:55 -0400 Subject: schemacell refactor started --- .../collectionSchema/SchemaCellField.tsx | 119 ++++++++++++++++++++- .../collectionSchema/SchemaTableCell.tsx | 2 +- 2 files changed, 116 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index e1059b8fc..5048bf899 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -8,6 +8,15 @@ import { FieldView, FieldViewProps } from "../../nodes/FieldView"; import { ObjectField } from "../../../../fields/ObjectField"; import { Doc } from "../../../../fields/Doc"; import { DocumentView } from "../../nodes/DocumentView"; +import { date } from "serializr"; +import { createRoot } from "react-dom/client"; +import DatePicker from "react-datepicker"; +import { emptyFunction } from "../../../../Utils"; +import { DateField } from "../../../../fields/DateField"; + +enum EleType { + plainText, fieldReference, date, boolean +} export interface SchemaCellFieldProps { contents: any; @@ -34,6 +43,7 @@ export class SchemaCellField extends ObservableReactComponent) { + this.addReactComponents(); super.componentDidUpdate(prevProps); if (this._editing && this._props.editing === false) { this.finalizeEdit(false, true, false); @@ -116,12 +127,31 @@ export class SchemaCellField extends ObservableReactComponent { + addReactComponents = () => { + if (!this._inputref) return; + + const dateRefs = Array.from(this._inputref.querySelectorAll('.date-placeholder')); + + dateRefs.forEach(ref => { + const root = createRoot(ref); + root.render(); + }) + } + + generateSpan = (text: string, cell: HTMLDivElement | undefined): JSX.Element => { const selfRef = text === this.selfRefPattern; - return `${text}`; + return ( + + {text} + + ); } makeSpans = (content: string) => { + const spans: JSX.Element[] = []; let chunkedText = content; const pattern = /(this|d(\d+))\.(\w+)/g; @@ -140,13 +170,89 @@ export class SchemaCellField extends ObservableReactComponent { - chunkedText = chunkedText.replace(match, this.generateSpan(match, cells.get(match))); + chunkedText = chunkedText.replace(match, ''); + spans.push(this.generateSpan(match, cells.get(match))); ++matchNum; }) + chunkedText = chunkedText.replace(/{{date}}/g, `placeholder text`); + console.log(chunkedText) + return chunkedText; } + verifyCellRef = (text: string): [string, HTMLDivElement | undefined] | undefined => { + const pattern = /(this|d(\d+))\.(\w+)/g; + let matchedText: string = ''; + let matchedCell: HTMLDivElement | undefined = undefined; + let match: RegExpExecArray | null; + + while ((match = pattern.exec(text)) !== null) { + const cells = this._props.getCells(match[0]); + if (cells.length) { + matchedText = match[0]; + matchedCell = cells[0]; + } + } + + if (!matchedText && !matchedCell) return undefined; + else return [matchedText, matchedCell]; + } + + elementsFromText = (chunks: string[]): JSX.Element[] => { + const eles: any[] = []; + + chunks.forEach(text => { + const cellRef = this.verifyCellRef(text); + if (cellRef) { + eles.push(this.generateSpan(cellRef[0], cellRef[1])); + } else if (!text.replace('{{date}}', '')){ + eles.push(); + } else if (!text.replace('{{boolean}}', '')) { + eles.push(
boolean thing
); + } else { + eles.push({text}); + } + }); + + return eles; + } + + parseElements = () => { + let string: string = this._unrenderedContent; + if (string.startsWith(':')) string = string.slice(1); + if (string.startsWith('=')) string = string.slice(1); + + const chunks: string[] = []; + + let subStr: string = ''; + let currChar = ''; + for (let i = 0; i < string.length; i++){ + currChar = string[i]; + if ((currChar === ' ' && subStr.trim()) || (currChar !== ' ' && !subStr.trim())) { + chunks.push(subStr); + subStr = currChar; + } else { + subStr += currChar; + } + } + + if (subStr) {chunks.push(subStr)}; + + return this.elementsFromText(chunks); + } + + // ` | undefined) => { + // if ((value?.nativeEvent as any).shiftKey) { + // this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); + // } else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); + // })} + // />` + @action setContent = (content: string, restoreCursorPos?: boolean) => { const pos = this.cursorPosition; @@ -235,6 +341,7 @@ export class SchemaCellField extends ObservableReactComponent { @@ -351,8 +458,12 @@ export class SchemaCellField extends ObservableReactComponent e.stopPropagation} onPointerUp={e => e.stopPropagation} onPointerMove={e => {e.stopPropagation(); e.preventDefault()}} - dangerouslySetInnerHTML={{ __html: this._displayedContent }} + suppressContentEditableWarning={true} + //dangerouslySetInnerHTML={{ __html: this._displayedContent }} > + {this.parseElements().map((ele, index) => { + return
{ele}
+ })}
); } diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index e2a05da7f..7d29e40cc 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -389,7 +389,7 @@ export class SchemaDateCell extends ObservableReactComponent -
+
{pointerEvents === 'none' ? null : ( -- cgit v1.2.3-70-g09d2 From e7235baa7ed998908dec8bf48e4c244594aa76bb Mon Sep 17 00:00:00 2001 From: Nathan-SR <144961007+Nathan-SR@users.noreply.github.com> Date: Sun, 8 Sep 2024 18:42:12 -0400 Subject: schema changes reverted --- .../collectionSchema/CollectionSchemaView.tsx | 3 +- .../collectionSchema/SchemaCellField.tsx | 123 +-------------------- .../collectionSchema/SchemaColumnHeader.tsx | 2 +- .../collections/collectionSchema/SchemaRowBox.tsx | 5 +- .../collectionSchema/SchemaTableCell.tsx | 2 +- .../views/nodes/DataVizBox/DocCreatorMenu.tsx | 9 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 7 files changed, 16 insertions(+), 130 deletions(-) (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx') diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 12c342b9f..59ccec71f 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -46,7 +46,6 @@ import { SchemaCellField } from './SchemaCellField'; import { threadId } from 'worker_threads'; import { FontIconBox } from '../../nodes/FontIconBox/FontIconBox'; -// eslint-disable-next-line @typescript-eslint/no-var-requires const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore export const FInfotoColType: { [key: string]: ColumnType } = { @@ -1539,4 +1538,4 @@ class CollectionSchemaViewDocs extends React.Component ); } -} +} \ No newline at end of file diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index 3be9167fe..e1059b8fc 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -8,15 +8,6 @@ import { FieldView, FieldViewProps } from "../../nodes/FieldView"; import { ObjectField } from "../../../../fields/ObjectField"; import { Doc } from "../../../../fields/Doc"; import { DocumentView } from "../../nodes/DocumentView"; -import { date } from "serializr"; -import { createRoot } from "react-dom/client"; -import DatePicker from "react-datepicker"; -import { emptyFunction } from "../../../../Utils"; -import { DateField } from "../../../../fields/DateField"; - -enum EleType { - plainText, fieldReference, date, boolean -} export interface SchemaCellFieldProps { contents: any; @@ -43,7 +34,6 @@ export class SchemaCellField extends ObservableReactComponent { - // if (!this._inputref) return; - - // const dateRefs = Array.from(this._inputref.querySelectorAll('.date-placeholder')); - - // dateRefs.forEach(ref => { - // const root = createRoot(ref); - // root.render(); - // }) - // } - - generateSpan = (text: string, cell: HTMLDivElement | undefined): JSX.Element => { + generateSpan = (text: string, cell: HTMLDivElement | undefined) => { const selfRef = text === this.selfRefPattern; - const color: string | undefined = cell?.style.borderTop.replace('2px solid', ''); - return ( - - {text} - - ); + return `${text}`; } makeSpans = (content: string) => { - const spans: JSX.Element[] = []; let chunkedText = content; const pattern = /(this|d(\d+))\.(\w+)/g; @@ -170,93 +140,17 @@ export class SchemaCellField extends ObservableReactComponent { - chunkedText = chunkedText.replace(match, ''); - spans.push(this.generateSpan(match, cells.get(match))); + chunkedText = chunkedText.replace(match, this.generateSpan(match, cells.get(match))); ++matchNum; }) - chunkedText = chunkedText.replace(/{{date}}/g, `placeholder text`); - return chunkedText; } - verifyCellRef = (text: string): [string, HTMLDivElement | undefined] | undefined => { - const pattern = /(this|d(\d+))\.(\w+)/g; - let matchedText: string = ''; - let matchedCell: HTMLDivElement | undefined = undefined; - let match: RegExpExecArray | null; - - while ((match = pattern.exec(text)) !== null) { - const cells = this._props.getCells(match[0]); - if (cells.length) { - matchedText = match[0]; - matchedCell = cells[0]; - } - } - - if (!matchedText && !matchedCell) return undefined; - else return [matchedText, matchedCell]; - } - - elementsFromText = (chunks: string[]): JSX.Element[] => { - const eles: any[] = []; - - chunks.forEach(text => { - const cellRef = this.verifyCellRef(text); - if (cellRef) { - eles.push(this.generateSpan(cellRef[0], cellRef[1])); - } else if (text && !text.replace('{{date}}', '')){ - eles.push(); - } else if (text && !text.replace('{{boolean}}', '')) { - eles.push(boolean thing); - } else { - eles.push({text}); - } - }); - - return eles; - } - - parseElements = (content: string) => { - let string: string = content; - if (string.startsWith(':')) string = string.slice(1); - if (string.startsWith('=')) string = string.slice(1); - - const chunks: string[] = []; - - let subStr: string = ''; - let currChar = ''; - for (let i = 0; i < string.length; i++){ - currChar = string[i]; - if (((string.charCodeAt(i) === 32 || string.charCodeAt(i) === 160) && subStr.trim()) || (currChar !== ' ' && !subStr.trim())) { - chunks.push(subStr); - subStr = currChar; - } else { - subStr += currChar; - } - } - - if (subStr) {chunks.push(subStr)}; - - return this.elementsFromText(chunks); - } - - // ` | undefined) => { - // if ((value?.nativeEvent as any).shiftKey) { - // this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); - // } else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); - // })} - // />` - @action setContent = (content: string, restoreCursorPos?: boolean) => { const pos = this.cursorPosition; - this._displayedContent = content; - this._displayedElements = this.parseElements(content); + this._displayedContent = this.makeSpans(content); restoreCursorPos && setTimeout(() => this.setCursorPosition(pos)); } @@ -339,9 +233,8 @@ export class SchemaCellField extends ObservableReactComponent this.parseElements(this._displayedContent).length) this.setContent(targVal, true); + if (this.shouldUpdate(prevVal, targVal)) {this.setContent(targVal, true)}; this.setupRefSelect(this.refSelectConditionMet); - console.log(this.parseElements(targVal)); }; setupRefSelect = (enabled: boolean) => { @@ -458,12 +351,8 @@ export class SchemaCellField extends ObservableReactComponent e.stopPropagation} onPointerUp={e => e.stopPropagation} onPointerMove={e => {e.stopPropagation(); e.preventDefault()}} - suppressContentEditableWarning={true} - //dangerouslySetInnerHTML={{ __html: this._displayedContent }} + dangerouslySetInnerHTML={{ __html: this._displayedContent }} > - {this._displayedElements.map((ele, index) => { - return {ele}; - })}
); } diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 40509c41b..9f6478041 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -249,4 +249,4 @@ export class SchemaColumnHeader extends ObservableReactComponent ); } -} +} \ No newline at end of file diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 72f5d8c25..ec94a8077 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -24,7 +24,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { infoState } from '../collectionFreeForm/CollectionFreeFormInfoState'; import { TbShieldX } from 'react-icons/tb'; -import { DocumentType } from '../../../documents/DocumentTypes'; interface SchemaRowBoxProps extends FieldViewProps { rowIndex: number; @@ -78,7 +77,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { icon: 'minus', }); const childDocs = DocListCast(this.Document[Doc.LayoutFieldKey(this.Document)]) - if (childDocs.length) { + if (this.Document.type === 'collection' && childDocs.length) { ContextMenu.Instance.addItem({ description: this.Document._childrenSharedWithSchema ? 'Remove children from schema' : 'Add children to schema', event: () => { @@ -197,4 +196,4 @@ export class SchemaRowBox extends ViewBoxBaseComponent() {
); } -} +} \ No newline at end of file diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 7d29e40cc..e2a05da7f 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -389,7 +389,7 @@ export class SchemaDateCell extends ObservableReactComponent -
+
{pointerEvents === 'none' ? null : ( diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index dcdd52c73..8273f3e09 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -375,7 +375,6 @@ export class DocCreatorMenu extends ObservableReactComponent { if (res && this._callCount === origCount) { this._suggestedTemplates = []; - this._GPTLoading = false; const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res); this.createGeneratedTemplates(templates, 500, 500); } @@ -714,7 +713,7 @@ export class DocCreatorMenu extends ObservableReactComponent { try { const renderedImages: Doc[] = await Promise.all( calls.map(async ([fieldNum, col]) => { - const sysPrompt = 'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' + fieldContent + ' **** The user prompt is: ' + col.desc; + const sysPrompt = 'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' + fieldContent + ' **** The user prompt is: ' + col.desc; const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT); console.log(sysPrompt, prompt); @@ -852,7 +851,6 @@ export class DocCreatorMenu extends ObservableReactComponent { const res = await gptAPICall(prompt, GPTCallType.TEMPLATE); if (res && this._callCount === origCount) { - this._GPTLoading = false; const assignments: {[templateTitle: string]: {[field: string]: string}} = JSON.parse(res); const brokenDownAssignments: [TemplateDocInfos, {[field: number]: Col}][] = []; @@ -889,7 +887,7 @@ export class DocCreatorMenu extends ObservableReactComponent { const renderedTemplates: Doc[] = await Promise.all(renderedTemplatePromises); - setTimeout(() => { this.setGSuggestedTemplates(renderedTemplates) }); + setTimeout(() => { this.setGSuggestedTemplates(renderedTemplates); this._GPTLoading = false }); }; @action setExpandedView = (info: {icon: ImageField, doc: Doc} | undefined) => { @@ -908,6 +906,7 @@ export class DocCreatorMenu extends ObservableReactComponent {
{this._expandedPreview ?
+