diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/views/collections/collectionSchema/CollectionSchemaView.tsx | 59 | ||||
| -rw-r--r-- | src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 84 |
2 files changed, 105 insertions, 38 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index db7bf8c43..f7a553da3 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -89,6 +89,7 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _draggedColIndex: number = 0; @observable _colBeingDragged: boolean = false; @observable _colKeysFiltered: boolean = false; + @observable _cellTags: ObservableMap = new ObservableMap<Doc, Array<string>>(); // target HTMLelement portal for showing a popup menu to edit cell values. public get MenuTarget() { @@ -302,9 +303,11 @@ export class CollectionSchemaView extends CollectionSubView() { addNewKey = (key: string, defaultVal: any) => { if (this._newFieldType == ColumnType.Equation) { this.childDocs.forEach(doc => { - const eq = this.parseEquation(defaultVal); - doc[DocData][key] = this.parsedEquationResult(eq, doc); - this.setupAutoUpdate(eq, 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 => { @@ -542,11 +545,55 @@ export class CollectionSchemaView extends CollectionSubView() { } else this.addDocToSelection(doc, false); this._selectedCol = col; + if (this._lowestSelectedIndex === -1 || index < this._lowestSelectedIndex) this._lowestSelectedIndex = index; // let selectedIndexes: Array<Number> = this._selectedCells.map(doc => this.rowIndex(doc)); }; + getCellTag = (doc: Doc, col: number) => { + return this._cellTags.get(doc)[col]; + } + + populateCellTags = () => { + this.childDocs.forEach(doc => this.addTags(doc)); + } + + addTags = (doc: Doc) => { + const row = this.rowIndex(doc) + 1; + const tags = []; + for (let col = 1; col <= this._colEles.length; ++col){ + tags.push(this.numToChar(col) + row.toString()) + } + this._cellTags.set(doc, tags) + } + + modifyCellTags = (addingColumn: boolean) => { + if (addingColumn) { + const colTag = this.numToChar(this._colEles.length); + this._cellTags.forEach((tags, row) => { + const newTag = colTag + this.rowIndex(row); + tags.push(newTag); + }); + } else { + this._cellTags.forEach(tags => { + if (tags.length > 0) { + tags.pop(); + } + }) + } + } + + numToChar = (num: number) => { + let result = ''; + while (num > 0) { + let remainder = (num - 1) % 26; + result = String.fromCharCode(65 + remainder) + result; + num = Math.floor((num - 1) / 26); + } + return result; + } + @action deselectCell = (doc: Doc) => { this._selectedCells && (this._selectedCells = this._selectedCells.filter(d => d !== doc)); @@ -936,6 +983,11 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get keysDropdown() { return ( <div className="schema-key-search"> + <button + className="schema-column-menu-button" + onClick={() => this.toggleMenuKeyFilter()}> + {this._colKeysFiltered ? "All keys" : "Active keys only"} + </button> <div className="schema-column-menu-button" onPointerDown={action((e: any) => { @@ -989,7 +1041,6 @@ export class CollectionSchemaView extends CollectionSubView() { return ( <div className="schema-column-menu" style={{ left: 0, minWidth: CollectionSchemaView._minColWidth }}> <input className="schema-key-search-input" type="text" onKeyDown={this.onSearchKeyDown} onChange={this.updateKeySearch} onPointerDown={e => e.stopPropagation()} /> - <button className="schema-column-menu-button" onClick={() => this.toggleMenuKeyFilter()}>{this._colKeysFiltered ? "All keys" : "Active keys only"}</button> {this._makeNewField ? this.newFieldMenu : this.keysDropdown} </div> ); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 5874364e0..c1677b024 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, returnEmptyDocViewList } from '../../StyleProvider'; +import { DefaultStyleProvider } from '../../StyleProvider'; import { Colors } from '../../global/globalEnums'; -import { DocumentView } from '../../nodes/DocumentView'; +import { DocFocusOrOpen, returnEmptyDocViewList } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { FInfotoColType } from './CollectionSchemaView'; @@ -59,14 +59,6 @@ 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<SchemaTableCellProps> { constructor(props: SchemaTableCellProps) { @@ -75,7 +67,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro } static addFieldDoc = (docs: Doc | Doc[] /* , where: OpenWhere */) => { - DocumentView.FocusOrOpen(toList(docs)[0]); + DocFocusOrOpen(toList(docs)[0]); return true; }; public static renderProps(props: SchemaTableCellProps) { @@ -122,6 +114,11 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro return { color, textDecoration, fieldProps, cursor, pointerEvents }; } + @computed get selected() { + const selectedDocs: Doc[] | undefined = this._props.selectedCells(); + return this._props.isRowActive() && selectedDocs?.filter(doc => doc === this._props.Document).length !== 0 && this._props.selectedCol() === this._props.col; + } + @computed get defaultCellContent() { const { color, textDecoration, fieldProps, pointerEvents } = SchemaTableCell.renderProps(this._props); @@ -135,12 +132,12 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro pointerEvents, }}> <EditableView - ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} + ref={r => this.selected && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} contents={undefined} fieldContents={fieldProps} - editing={selectedCell(this._props) ? undefined : false} + editing={this.selected ? undefined : false} GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { @@ -160,27 +157,39 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro get getCellType() { const columnTypeStr = this._props.getFinfo(this._props.fieldKey)?.fieldType; const cellValue = this._props.Document[this._props.fieldKey]; - if (cellValue instanceof ImageField) return ColumnType.Image; if (cellValue instanceof DateField) return ColumnType.Date; if (cellValue instanceof RichTextField) return ColumnType.RTF; if (typeof cellValue === 'number') return ColumnType.Any; if (typeof cellValue === 'string' && columnTypeStr !== FInfoFieldType.enumeration) return ColumnType.Any; if (typeof cellValue === 'boolean') return ColumnType.Boolean; - if (columnTypeStr && columnTypeStr in FInfotoColType) return FInfotoColType[columnTypeStr]; + + if (columnTypeStr && columnTypeStr in FInfotoColType) { + return FInfotoColType[columnTypeStr]; + } return ColumnType.Any; } get content() { + const cellType: ColumnType = this.getCellType; // prettier-ignore - switch (this.getCellType) { - case ColumnType.Image: return <SchemaImageCell {...this._props} />; - case ColumnType.Boolean: return <SchemaBoolCell {...this._props} />; - case ColumnType.RTF: return <SchemaRTFCell {...this._props} />; + switch (cellType) { + case ColumnType.Image: return <SchemaImageCell {...this._props} />; + case ColumnType.Boolean: return <SchemaBoolCell {...this._props} />; + case ColumnType.RTF: return <SchemaRTFCell {...this._props} />; case ColumnType.Enumeration: return <SchemaEnumerationCell {...this._props} options={this._props.getFinfo(this._props.fieldKey)?.values?.map(val => Field.toString(val))} />; - case ColumnType.Date: return <SchemaDateCell {...this._props} />; - default: return this.defaultCellContent; + case ColumnType.Date: return <SchemaDateCell {...this._props} />; + default: return this.defaultCellContent; + } + } + + select = (shift: boolean, ctrl: boolean, e: React.MouseEvent<HTMLDivElement>) => { + 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); } } @@ -190,16 +199,9 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro className="schema-table-cell" onContextMenu={e => StopEvent(e)} onPointerDown={action(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); - } + this.select(e.shiftKey, e.ctrlKey, e); })} - style={{ padding: this._props.padding, maxWidth: this._props.maxWidth?.(), width: this._props.columnWidth() || undefined, border: selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> + 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} </div> ); @@ -329,14 +331,20 @@ export class SchemaRTFCell extends ObservableReactComponent<SchemaTableCellProps makeObservable(this); } + @computed get selected() { + const selected = this._props.selectedCells(); + return this._props.isRowActive() && selected && selected?.filter(doc => 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 = () => !!selectedCell(this._props); + selectedFunc = () => this.selected; render() { const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props); fieldProps.isContentActive = this.selectedFunc; return ( - <div className="schemaRTFCell" style={{ fontStyle: selectedCell(this._props) ? undefined : 'italic', color, textDecoration, cursor, pointerEvents }}> - {selectedCell(this._props) ? <FormattedTextBox {...fieldProps} autoFocus onBlur={() => this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))} + <div className="schemaRTFCell" style={{ fontStyle: this.selected ? undefined : 'italic', color, textDecoration, cursor, pointerEvents }}> + {this.selected ? <FormattedTextBox {...fieldProps} autoFocus onBlur={() => this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))} </div> ); } @@ -348,6 +356,10 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp makeObservable(this); } + @computed get selected() { + const selected = this._props.selectedCells(); + return this._props.isRowActive() && selected && selected?.filter(doc => doc === this._props.Document).length !== 0 && this._props.selectedCol() === this._props.col; + } render() { const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props); return ( @@ -365,7 +377,7 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp <EditableView contents={undefined} fieldContents={fieldProps} - editing={selectedCell(this._props) ? undefined : false} + editing={this.selected ? undefined : false} GetValue={() => Field.toKeyValueString(this._props.Document, this._props.fieldKey)} SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { @@ -389,6 +401,10 @@ export class SchemaEnumerationCell extends ObservableReactComponent<SchemaTableC makeObservable(this); } + @computed get selected() { + const selected = this._props.selectedCells(); + return this._props.isRowActive() && selected && selected?.filter(doc => 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 })); |
