diff options
author | mehekj <mehek.jethani@gmail.com> | 2023-04-27 00:41:43 -0400 |
---|---|---|
committer | mehekj <mehek.jethani@gmail.com> | 2023-04-27 00:41:43 -0400 |
commit | bc550e43b6042176cf59f04cbff51e1b21adaa8a (patch) | |
tree | 9b0e34fe9d3d3c9ba2bf33e7cd4898479e535097 | |
parent | d58a3350b1d90f701f5cc18a69f51954c88ea30c (diff) |
trying to get schema keyboard controls working
3 files changed, 78 insertions, 31 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index f6dc2a3d7..92a04f5ec 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -74,6 +74,7 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _menuValue: string = ''; @observable _filterColumnIndex: number | undefined; @observable _filterSearchValue: string = ''; + @observable _selectedCell: [Doc, number] | undefined; get fieldInfos() { const docs = this.childDocs; @@ -174,8 +175,11 @@ export class CollectionSchemaView extends CollectionSubView() { !e.shiftKey && this.clearSelection(); const newDoc = this.sortedDocs.docs[lastIndex + 1]; if (this._selectedDocs.includes(newDoc)) SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(curDoc)); - else this.addDocToSelection(newDoc, e.shiftKey, lastIndex + 1); - this.scrollToDoc(newDoc, {}); + else { + this.addDocToSelection(newDoc, e.shiftKey, lastIndex + 1); + this._selectedCell && (this._selectedCell[0] = newDoc); + this.scrollToDoc(newDoc, {}); + } } e.stopPropagation(); e.preventDefault(); @@ -191,13 +195,37 @@ export class CollectionSchemaView extends CollectionSubView() { !e.shiftKey && this.clearSelection(); const newDoc = this.sortedDocs.docs[firstIndex - 1]; if (this._selectedDocs.includes(newDoc)) SelectionManager.DeselectView(DocumentManager.Instance.getFirstDocumentView(curDoc)); - else this.addDocToSelection(newDoc, e.shiftKey, firstIndex - 1); - this.scrollToDoc(newDoc, {}); + else { + this.addDocToSelection(newDoc, e.shiftKey, firstIndex - 1); + this._selectedCell && (this._selectedCell[0] = newDoc); + this.scrollToDoc(newDoc, {}); + } } e.stopPropagation(); e.preventDefault(); } break; + case 'ArrowRight': + if (this._selectedCell) { + this._selectedCell[1] = Math.min(this._selectedCell[1] + 1, this.columnKeys.length - 1); + } else if (this._selectedDocs.length > 0) { + this.selectCell(this._selectedDocs[0], 0); + } + break; + case 'ArrowLeft': + if (this._selectedCell) { + this._selectedCell[1] = Math.max(this._selectedCell[1] - 1, 0); + } else if (this._selectedDocs.length > 0) { + this.selectCell(this._selectedDocs[0], 0); + } + break; + case 'Backspace': { + this.removeDocument(this._selectedDocs); + break; + } + case 'Escape': { + this._selectedCell = undefined; + } } } }; @@ -392,6 +420,11 @@ export class CollectionSchemaView extends CollectionSubView() { } }; + @action + selectCell = (doc: Doc, index: number) => { + this._selectedCell = [doc, index]; + }; + sortedSelectedDocs = () => this.sortedDocs.docs.filter(doc => this._selectedDocs.includes(doc)); setDropIndex = (index: number) => (this._closestDropIndex = index); @@ -428,7 +461,7 @@ export class CollectionSchemaView extends CollectionSubView() { const pushedAndDraggedDocs = [...pushedDocs, ...draggedDocs]; const removed = this.childDocs.slice().filter(doc => !pushedAndDraggedDocs.includes(doc)); this.dataDoc[this.fieldKey ?? 'data'] = new List<Doc>([...removed, ...draggedDocs, ...pushedDocs]); - SelectionManager.DeselectAll(); + this.clearSelection(); draggedDocs.forEach(doc => { const draggedView = DocumentManager.Instance.getFirstDocumentView(doc); if (draggedView) DocumentManager.Instance.RemoveView(draggedView); diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 79808d8f8..f5a16cec0 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -123,6 +123,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() { <SchemaTableCell key={key} Document={this.rootDoc} + col={index} schemaView={this.schemaView} fieldKey={key} columnWidth={this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth} diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 2325339fc..2b61ea261 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -11,13 +11,16 @@ import { CollectionSchemaView, ColumnType, FInfotoColType } from './CollectionSc import './CollectionSchemaView.scss'; import { action, computed, observable } from 'mobx'; import { extname } from 'path'; -import { Cast, DateCast } from '../../../../fields/Types'; +import { Cast, DateCast, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { DateField } from '../../../../fields/DateField'; import DatePicker from 'react-datepicker'; +import { Colors } from '../../global/globalEnums'; +import { SelectionManager } from '../../../util/SelectionManager'; export interface SchemaTableCellProps { Document: Doc; + col: number; schemaView: CollectionSchemaView | undefined; fieldKey: string; columnWidth: number; @@ -27,10 +30,23 @@ export interface SchemaTableCellProps { @observer export class SchemaTableCell extends React.Component<SchemaTableCellProps> { - get readOnly() { + private _editorRef: EditableView | null = null; + + @computed get readOnly() { return this.props.schemaView?.fieldInfos[this.props.fieldKey]?.readOnly ?? false; } + @computed get selected() { + const selected: [Doc, number] | undefined = this.props.schemaView?._selectedCell; + return this.props.isRowActive() && selected && selected[0] == this.props.Document && selected[1] == this.props.col; + } + + componentDidUpdate() { + if (!this.selected) { + this._editorRef?.setIsFocused(false); + } + } + get defaultCellContent() { const props: FieldViewProps = { Document: this.props.Document, @@ -60,6 +76,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { return ( <div className="schemacell-edit-wrapper" style={{ cursor: !this.readOnly ? 'text' : 'default', pointerEvents: !this.readOnly && this.props.isRowActive() ? 'all' : 'none' }}> <EditableView + ref={ref => (this._editorRef = ref)} contents={<FieldView {...props} />} GetValue={() => Field.toKeyValueString(this.props.Document, this.props.fieldKey)} SetValue={(value: string, shiftDown?: boolean, enterKey?: boolean) => { @@ -68,20 +85,12 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { } return KeyValueBox.SetField(this.props.Document, this.props.fieldKey, value); }} - editing={this.props.isRowActive() ? undefined : false} + editing={this.selected ? undefined : false} /> </div> ); } - getCellWithContent(content: any) { - return ( - <div className="schema-table-cell" style={this.props.isRowActive() && !this.readOnly ? { width: this.props.columnWidth } : { width: this.props.columnWidth }}> - {content} - </div> - ); - } - get getCellType() { const columnTypeStr = this.props.schemaView?.fieldInfos[this.props.fieldKey]?.fieldType; if (columnTypeStr) { @@ -99,7 +108,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { return ColumnType.Any; } - render() { + get content() { const cellType: ColumnType = this.getCellType; switch (cellType) { case ColumnType.Image: @@ -107,14 +116,27 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { case ColumnType.Date: // return <SchemaDateCell {...this.props} />; default: - return this.getCellWithContent(this.defaultCellContent); + return this.defaultCellContent; } } + + render() { + return ( + <div + className="schema-table-cell" + onPointerDown={action(e => { + if (!this.selected) this.props.schemaView?.selectCell(this.props.Document, this.props.col); + })} + style={{ width: this.props.columnWidth, border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> + {this.content} + </div> + ); + } } // mj: most of this is adapted from old schema code so I'm not sure what it does tbh @observer -export class SchemaImageCell extends SchemaTableCell { +export class SchemaImageCell extends React.Component<SchemaTableCellProps> { @observable _previewRef: HTMLImageElement | undefined; choosePath(url: URL) { @@ -164,7 +186,7 @@ export class SchemaImageCell extends SchemaTableCell { document.body.removeChild(this._previewRef); }; - get content() { + render() { const aspect = Doc.NativeAspect(this.props.Document); // aspect ratio // let width = Math.max(75, this.props.columnWidth); // get a with that is no smaller than 75px // const height = Math.max(75, width / aspect); // get a height either proportional to that or 75 px @@ -173,14 +195,10 @@ export class SchemaImageCell extends SchemaTableCell { return <img src={this.url} width={width} height={height} style={{}} draggable="false" onPointerEnter={this.showHoverPreview} onPointerMove={this.moveHoverPreview} onPointerLeave={this.removeHoverPreview} />; } - - render() { - return this.getCellWithContent(this.content); - } } @observer -export class SchemaDateCell extends SchemaTableCell { +export class SchemaDateCell extends React.Component<SchemaTableCellProps> { @observable _pickingDate: boolean = false; @computed get date(): DateField { @@ -199,12 +217,7 @@ export class SchemaDateCell extends SchemaTableCell { //} }; - get content() { - return <DatePicker dateFormat={'Pp'} selected={this.date.date} onChange={(date: any) => this.handleChange(date)} />; - // return !this._pickingDate ? <div onPointerDown={action(() => (this._pickingDate = true))}>{this.defaultCellContent}</div> : <DatePicker dateFormat={'Pp'} selected={this.date.date} onChange={(date: any) => this.handleChange(date)} />; - } - render() { - return this.getCellWithContent(this.content); + return <DatePicker dateFormat={'Pp'} selected={this.date.date} onChange={(date: any) => this.handleChange(date)} />; } } |