diff options
| author | bobzel <zzzman@gmail.com> | 2023-12-21 14:55:48 -0500 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2023-12-21 14:55:48 -0500 |
| commit | 1caba64ee0f32ee8af79263cd4ef2a8bc5d5146e (patch) | |
| tree | 0fa0e957d1f342fdc6ed4a4b43f5dddfddb1298a /src/client/views/collections/collectionSchema/CollectionSchemaView.tsx | |
| parent | 02eb7da95df283606d4275a22d9451cef371c3b5 (diff) | |
| parent | 2691b951d96f2ce7652acbea9e340b61737b3b57 (diff) | |
Merge branch 'moreUpgrading' into dataViz-annotations
Diffstat (limited to 'src/client/views/collections/collectionSchema/CollectionSchemaView.tsx')
| -rw-r--r-- | src/client/views/collections/collectionSchema/CollectionSchemaView.tsx | 129 |
1 files changed, 65 insertions, 64 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 190e4ff2a..2546f5b02 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -1,7 +1,7 @@ -import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, ObservableMap, observe } from 'mobx'; +import { action, computed, makeObservable, observable, ObservableMap, observe } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; @@ -18,6 +18,7 @@ import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; import { DocFocusOptions, DocumentView, DocumentViewProps } from '../../nodes/DocumentView'; import { KeyValueBox } from '../../nodes/KeyValueBox'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DefaultStyleProvider, StyleProp } from '../../StyleProvider'; import { CollectionSubView } from '../CollectionSubView'; import './CollectionSchemaView.scss'; @@ -57,6 +58,11 @@ export class CollectionSchemaView extends CollectionSubView() { private _tableContentRef: HTMLDivElement | null = null; private _menuTarget = React.createRef<HTMLDivElement>(); + constructor(props: any) { + super(props); + makeObservable(this); + } + static _rowHeight: number = 50; static _rowSingleLineHeight: number = 32; public static _minColWidth: number = 25; @@ -68,16 +74,16 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _menuKeys: string[] = []; @observable _rowEles: ObservableMap = new ObservableMap<Doc, HTMLDivElement>(); @observable _colEles: HTMLDivElement[] = []; - @observable _displayColumnWidths: number[] | undefined; - @observable _columnMenuIndex: number | undefined; + @observable _displayColumnWidths: number[] | undefined = undefined; + @observable _columnMenuIndex: number | undefined = undefined; @observable _newFieldWarning: string = ''; @observable _makeNewField: boolean = false; @observable _newFieldDefault: any = 0; @observable _newFieldType: ColumnType = ColumnType.Number; @observable _menuValue: string = ''; - @observable _filterColumnIndex: number | undefined; + @observable _filterColumnIndex: number | undefined = undefined; @observable _filterSearchValue: string = ''; - @observable _selectedCell: [Doc, number] | undefined; + @observable _selectedCell: [Doc, number] | undefined = undefined; // target HTMLelement portal for showing a popup menu to edit cell values. public get MenuTarget() { @@ -85,12 +91,12 @@ export class CollectionSchemaView extends CollectionSubView() { } @computed get _selectedDocs() { - const selected = SelectionManager.Docs().filter(doc => Doc.AreProtosEqual(DocCast(doc.embedContainer), this.rootDoc)); + const selected = SelectionManager.Docs.filter(doc => Doc.AreProtosEqual(DocCast(doc.embedContainer), this.Document)); if (!selected.length) { - for (const sel of SelectionManager.Docs()) { + for (const sel of SelectionManager.Docs) { const contextPath = DocumentManager.GetContextPath(sel, true); - if (contextPath.includes(this.rootDoc)) { - const parentInd = contextPath.indexOf(this.rootDoc); + if (contextPath.includes(this.Document)) { + const parentInd = contextPath.indexOf(this.Document); return parentInd < contextPath.length - 1 ? [contextPath[parentInd + 1]] : []; } } @@ -107,7 +113,7 @@ export class CollectionSchemaView extends CollectionSubView() { } @computed get tableWidth() { - return this.props.PanelWidth() - this.previewWidth - (this.previewWidth === 0 ? 0 : CollectionSchemaView._previewDividerWidth); + return this._props.PanelWidth() - this.previewWidth - (this.previewWidth === 0 ? 0 : CollectionSchemaView._previewDividerWidth); } @computed get columnKeys() { @@ -139,14 +145,13 @@ export class CollectionSchemaView extends CollectionSubView() { return BoolCast(this.layoutDoc.sortDesc); } - @action componentDidMount() { - this.props.setContentView?.(this); + this._props.setContentView?.(this); document.addEventListener('keydown', this.onKeyDown); Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => this.fieldInfos.set(pair[0], pair[1])); this._keysDisposer = observe( - this.rootDoc[this.fieldKey ?? 'data'] as List<Doc>, + this.dataDoc[this.fieldKey ?? 'data'] as List<Doc>, change => { switch (change.type as any) { case 'splice': @@ -154,7 +159,7 @@ export class CollectionSchemaView extends CollectionSubView() { (change as any).added.forEach((doc: Doc) => // for each document added Doc.GetAllPrototypes(doc.value as Doc).forEach(proto => // for all of its prototypes (and itself) Object.keys(proto).forEach(action(key => // check if any of its keys are new, and add them - !this.fieldInfos.get(key) && this.fieldInfos.set(key, new FInfo('')))))); + !this.fieldInfos.get(key) && this.fieldInfos.set(key, new FInfo(key, key === 'author')))))); break; case 'update': //let oldValue = change.oldValue; // fill this in if the entire child list will ever be reassigned with a new list } @@ -239,7 +244,6 @@ export class CollectionSchemaView extends CollectionSubView() { }; @undoBatch - @action setColumnSort = (field: string | undefined, desc: boolean = false) => { this.layoutDoc.sortField = field; this.layoutDoc.sortDesc = desc; @@ -248,7 +252,6 @@ export class CollectionSchemaView extends CollectionSubView() { addRow = (doc: Doc | Doc[]) => this.addDocument(doc); @undoBatch - @action changeColumnKey = (index: number, newKey: string, defaultVal?: any) => { if (!this.documentKeys.includes(newKey)) { this.addNewKey(newKey, defaultVal); @@ -260,7 +263,6 @@ export class CollectionSchemaView extends CollectionSubView() { }; @undoBatch - @action addColumn = (key: string, defaultVal?: any) => { if (!this.documentKeys.includes(key)) { this.addNewKey(key, defaultVal); @@ -281,7 +283,6 @@ export class CollectionSchemaView extends CollectionSubView() { addNewKey = (key: string, defaultVal: any) => this.childDocs.forEach(doc => (doc[key] = defaultVal)); @undoBatch - @action removeColumn = (index: number) => { if (this.columnKeys.length === 1) return; const currWidths = this.storedColumnWidths.slice(); @@ -320,8 +321,8 @@ export class CollectionSchemaView extends CollectionSubView() { change = this._displayColumnWidths[shrinking] - CollectionSchemaView._minColWidth; } - this._displayColumnWidths[shrinking] -= change * this.props.ScreenToLocalTransform().Scale; - this._displayColumnWidths[growing] += change * this.props.ScreenToLocalTransform().Scale; + this._displayColumnWidths[shrinking] -= change * this._props.ScreenToLocalTransform().Scale; + this._displayColumnWidths[growing] += change * this._props.ScreenToLocalTransform().Scale; return false; } @@ -335,7 +336,6 @@ export class CollectionSchemaView extends CollectionSubView() { }; @undoBatch - @action moveColumn = (fromIndex: number, toIndex: number) => { let currKeys = this.columnKeys.slice(); currKeys.splice(toIndex, 0, currKeys.splice(fromIndex, 1)[0]); @@ -379,7 +379,7 @@ export class CollectionSchemaView extends CollectionSubView() { @action highlightDropColumn = (e: PointerEvent) => { e.stopPropagation(); - const mouseX = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0]; + const mouseX = this._props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0]; const index = this.findDropIndex(mouseX); this._colEles.forEach((colRef, i) => { let leftStyle = ''; @@ -416,8 +416,8 @@ export class CollectionSchemaView extends CollectionSubView() { @action clearSelection = () => SelectionManager.DeselectAll(); - selectRows = (rootDoc: Doc, lastSelected: Doc) => { - const index = this.rowIndex(rootDoc); + selectRows = (doc: Doc, lastSelected: Doc) => { + const index = this.rowIndex(doc); const lastSelectedRow = this.rowIndex(lastSelected); const startRow = Math.min(lastSelectedRow, index); const endRow = Math.max(lastSelectedRow, index); @@ -437,10 +437,9 @@ export class CollectionSchemaView extends CollectionSubView() { setDropIndex = (index: number) => (this._closestDropIndex = index); - @action onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.columnDragData) { - const mouseX = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]; + const mouseX = this._props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]; const index = this.findDropIndex(mouseX); this.moveColumn(de.complete.columnDragData.colIndex, index ?? de.complete.columnDragData.colIndex); @@ -473,7 +472,6 @@ export class CollectionSchemaView extends CollectionSubView() { return false; }; - @action onExternalDrop = async (e: React.DragEvent): Promise<void> => { super.onExternalDrop(e, {}, undoBatch(action(docus => docus.map((doc: Doc) => this.addDocument(doc))))); }; @@ -485,7 +483,7 @@ export class CollectionSchemaView extends CollectionSubView() { const nativeWidth = this._previewRef!.getBoundingClientRect(); const minWidth = 40; const maxWidth = 1000; - const movedWidth = this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0]; + const movedWidth = this._props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0]; const width = movedWidth < minWidth ? minWidth : movedWidth > maxWidth ? maxWidth : movedWidth; this.layoutDoc.schema_previewWidth = width; return false; @@ -509,8 +507,8 @@ export class CollectionSchemaView extends CollectionSubView() { const found = this._tableContentRef && Array.from(this._tableContentRef.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]); if (found) { const rect = found.getBoundingClientRect(); - const localRect = this.props.ScreenToLocalTransform().transformBounds(rect.left, rect.top, rect.width, rect.height); - if (localRect.y < this.rowHeightFunc() || localRect.y + localRect.height > this.props.PanelHeight()) { + const localRect = this._props.ScreenToLocalTransform().transformBounds(rect.left, rect.top, rect.width, rect.height); + if (localRect.y < this.rowHeightFunc() || localRect.y + localRect.height > this._props.PanelHeight()) { let focusSpeed = options.zoomTime ?? 50; smoothScroll(focusSpeed, this._tableContentRef!, localRect.y + this._tableContentRef!.scrollTop - this.rowHeightFunc(), options.easeFunc); return focusSpeed; @@ -757,7 +755,7 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get renderFilterOptions() { const keyOptions: string[] = []; const columnKey = this.columnKeys[this._filterColumnIndex!]; - const allDocs = DocListCast(this.dataDoc[this.props.fieldKey]); + const allDocs = DocListCast(this.dataDoc[this._props.fieldKey]); allDocs.forEach(doc => { const value = StrCast(doc[columnKey]); if (!keyOptions.includes(value) && value !== '' && (this._filterSearchValue === '' || value.includes(this._filterSearchValue))) { @@ -781,9 +779,9 @@ export class CollectionSchemaView extends CollectionSubView() { onClick={e => e.stopPropagation()} onChange={action(e => { if (e.target.checked) { - Doc.setDocFilter(this.props.Document, columnKey, key, 'check'); + Doc.setDocFilter(this.Document, columnKey, key, 'check'); } else { - Doc.setDocFilter(this.props.Document, columnKey, key, 'remove'); + Doc.setDocFilter(this.Document, columnKey, key, 'remove'); } })} checked={bool} @@ -830,8 +828,8 @@ export class CollectionSchemaView extends CollectionSubView() { } rowHeightFunc = () => (BoolCast(this.layoutDoc._schema_singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight); sortedDocsFunc = () => this.sortedDocs; - isContentActive = () => this.props.isSelected() || this.props.isContentActive(); - screenToLocal = () => this.props.ScreenToLocalTransform().translate(-this.tableWidth, 0); + isContentActive = () => this._props.isSelected() || this._props.isContentActive(); + screenToLocal = () => this._props.ScreenToLocalTransform().translate(-this.tableWidth, 0); previewWidthFunc = () => this.previewWidth; render() { return ( @@ -840,7 +838,7 @@ export class CollectionSchemaView extends CollectionSubView() { <div className="schema-table" style={{ width: `calc(100% - ${this.previewWidth}px)` }} - onWheel={e => this.props.isContentActive() && e.stopPropagation()} + onWheel={e => this._props.isContentActive() && e.stopPropagation()} ref={r => { // prevent wheel events from passively propagating up through containers r?.addEventListener('wheel', (e: WheelEvent) => {}, { passive: false }); @@ -866,7 +864,7 @@ export class CollectionSchemaView extends CollectionSubView() { openContextMenu={this.openContextMenu} dragColumn={this.dragColumn} setColRef={this.setColRef} - isContentActive={this.props.isContentActive} + isContentActive={this._props.isContentActive} /> ))} </div> @@ -892,16 +890,15 @@ export class CollectionSchemaView extends CollectionSubView() { {Array.from(this._selectedDocs).lastElement() && ( <DocumentView Document={Array.from(this._selectedDocs).lastElement()} - DataDoc={undefined} fitContentsToBox={returnTrue} dontCenter={'y'} onClickScriptDisable="always" focus={emptyFunction} defaultDoubleClick={returnIgnore} - renderDepth={this.props.renderDepth + 1} + renderDepth={this._props.renderDepth + 1} rootSelected={this.rootSelected} PanelWidth={this.previewWidthFunc} - PanelHeight={this.props.PanelHeight} + PanelHeight={this._props.PanelHeight} isContentActive={returnTrue} isDocumentActive={returnFalse} ScreenToLocalTransform={this.screenToLocal} @@ -910,12 +907,12 @@ export class CollectionSchemaView extends CollectionSubView() { searchFilterDocs={this.searchFilterDocs} styleProvider={DefaultStyleProvider} docViewPath={returnEmptyDoclist} - moveDocument={this.props.moveDocument} + moveDocument={this._props.moveDocument} addDocument={this.addRow} - removeDocument={this.props.removeDocument} + removeDocument={this._props.removeDocument} whenChildContentsActiveChanged={returnFalse} - addDocTab={this.props.addDocTab} - pinToPres={this.props.pinToPres} + addDocTab={this._props.addDocTab} + pinToPres={this._props.pinToPres} bringToFront={returnFalse} /> )} @@ -939,7 +936,7 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP return ( <div className="schema-table-content" ref={this.props.setRef} style={{ height: `calc(100% - ${CollectionSchemaView._newNodeInputHeight + this.props.rowHeight()}px)` }}> {this.props.childDocs().docs.map((doc: Doc, index: number) => ( - <div className="schema-row-wrapper" style={{ height: this.props.rowHeight() }}> + <div key={doc[Id]} className="schema-row-wrapper" style={{ height: this.props.rowHeight() }}> <CollectionSchemaViewDoc doc={doc} schema={this.props.schema} index={index} rowHeight={this.props.rowHeight} /> </div> ))} @@ -956,9 +953,14 @@ interface CollectionSchemaViewDocProps { } @observer -class CollectionSchemaViewDoc extends React.Component<CollectionSchemaViewDocProps> { - tableWidthFunc = () => this.props.schema.tableWidth; - screenToLocalXf = () => this.props.schema.props.ScreenToLocalTransform().translate(0, -this.props.rowHeight() - this.props.index * this.props.rowHeight()); +class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaViewDocProps> { + constructor(props: any) { + super(props); + makeObservable(this); + } + + tableWidthFunc = () => this._props.schema.tableWidth; + screenToLocalXf = () => this._props.schema._props.ScreenToLocalTransform().translate(0, -this._props.rowHeight() - this._props.index * this._props.rowHeight()); noOpacityStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => { if (property === StyleProp.Opacity) return 1; return DefaultStyleProvider(doc, props, property); @@ -966,31 +968,30 @@ class CollectionSchemaViewDoc extends React.Component<CollectionSchemaViewDocPro render() { return ( <DocumentView - key={this.props.doc[Id]} - {...this.props.schema.props} - LayoutTemplate={this.props.schema.props.childLayoutTemplate} - LayoutTemplateString={SchemaRowBox.LayoutString(this.props.schema.props.fieldKey, this.props.index)} - Document={this.props.doc} - DataDoc={undefined} - renderDepth={this.props.schema.props.renderDepth + 1} + key={this._props.doc[Id]} + {...this._props.schema._props} + LayoutTemplate={this._props.schema._props.childLayoutTemplate} + LayoutTemplateString={SchemaRowBox.LayoutString(this._props.schema._props.fieldKey, this._props.index)} + Document={this._props.doc} + renderDepth={this._props.schema._props.renderDepth + 1} PanelWidth={this.tableWidthFunc} - PanelHeight={this.props.rowHeight} + PanelHeight={this._props.rowHeight} styleProvider={this.noOpacityStyleProvider} waitForDoubleClickToClick={returnNever} defaultDoubleClick={returnIgnore} dragAction="move" onClickScriptDisable="always" - focus={this.props.schema.focusDocument} - childFilters={this.props.schema.childDocFilters} - childFiltersByRanges={this.props.schema.childDocRangeFilters} - searchFilterDocs={this.props.schema.searchFilterDocs} - rootSelected={this.props.schema.rootSelected} + focus={this._props.schema.focusDocument} + childFilters={this._props.schema.childDocFilters} + childFiltersByRanges={this._props.schema.childDocRangeFilters} + searchFilterDocs={this._props.schema.searchFilterDocs} + rootSelected={this._props.schema.rootSelected} ScreenToLocalTransform={this.screenToLocalXf} bringToFront={emptyFunction} dragWhenActive={true} - isDocumentActive={this.props.schema.props.childDocumentsActive?.() ? this.props.schema.props.isDocumentActive : this.props.schema.isContentActive} + isDocumentActive={this._props.schema._props.childDocumentsActive?.() ? this._props.schema._props.isDocumentActive : this._props.schema.isContentActive} isContentActive={emptyFunction} - whenChildContentsActiveChanged={this.props.schema.props.whenChildContentsActiveChanged} + whenChildContentsActiveChanged={this._props.schema._props.whenChildContentsActiveChanged} hideDecorations={true} hideTitle={true} hideDocumentButtonBar={true} |
