diff options
Diffstat (limited to 'src/client/views/collections/collectionSchema/CollectionSchemaView.tsx')
| -rw-r--r-- | src/client/views/collections/collectionSchema/CollectionSchemaView.tsx | 327 |
1 files changed, 164 insertions, 163 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 0076caaf8..aef97e723 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -1,12 +1,11 @@ -/* eslint-disable no-restricted-syntax */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { IconButton, Popup, PopupTrigger, Size, Type } from 'browndash-components'; -import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObservable, observable, observe, override, reaction, runInAction } from 'mobx'; +import { IconButton, Size } from 'browndash-components'; +import { IReactionDisposer, Lambda, ObservableMap, action, computed, makeObservable, observable, observe, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ClientUtils, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; -import { Doc, DocListCast, Field, FieldType, IdToDoc, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; @@ -14,10 +13,13 @@ import { ColumnType } from '../../../../fields/SchemaHeaderField'; import { BoolCast, NumCast, StrCast } from '../../../../fields/Types'; import { DocUtils } from '../../../documents/DocUtils'; import { Docs, DocumentOptions, FInfo } from '../../../documents/Documents'; +import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; import { dropActionType } from '../../../util/DropActionTypes'; +import { SnappingManager } from '../../../util/SnappingManager'; import { undoBatch, undoable } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; +import { ContextMenuProps } from '../../ContextMenuItem'; import { EditableView } from '../../EditableView'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { StyleProp } from '../../StyleProp'; @@ -28,25 +30,23 @@ import { FieldViewProps } from '../../nodes/FieldView'; import { FocusViewOptions } from '../../nodes/FocusViewOptions'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionSchemaView.scss'; +import { SchemaCellField } from './SchemaCellField'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; -import { ContextMenuProps } from '../../ContextMenuItem'; -import { DocumentManager } from '../../../util/DocumentManager'; -import { SchemaCellField } from './SchemaCellField'; -import { SnappingManager } from '../../../util/SnappingManager'; /** * The schema view offers a spreadsheet-like interface for users to interact with documents. Within the schema, - * each doc is represented by its own row. Each column represents a field, for example the author or title fields. + * each doc is represented by its own row. Each column represents a field, for example the author or title fields. * Users can apply varoius filters and sorts to columns to change what is displayed. The schemaview supports equations for * cell linking. - * + * * This class supports the main functionality for choosing which docs to render in the view, applying visual - * updates to rows and columns (such as user dragging or sort-related highlighting), applying edits to multiple cells + * updates to rows and columns (such as user dragging or sort-related highlighting), applying edits to multiple cells * at once, and applying filters and sorts to columns. It contains SchemaRowBoxes (which themselves contain SchemaTableCells, * and SchemaCellFields) and SchemaColumnHeaders. */ +// eslint-disable-next-line @typescript-eslint/no-require-imports const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore export const FInfotoColType: { [key: string]: ColumnType } = { @@ -63,7 +63,7 @@ const defaultColumnKeys: string[] = ['title', 'type', 'author', 'author_date', ' @observer export class CollectionSchemaView extends CollectionSubView() { - private _keysDisposer: any; + private _keysDisposer?: Lambda; private _disposers: { [name: string]: IReactionDisposer } = {}; private _previewRef: HTMLDivElement | null = null; private _makeNewColumn: boolean = false; @@ -71,13 +71,14 @@ export class CollectionSchemaView extends CollectionSubView() { private _tableContentRef: HTMLDivElement | null = null; private _menuTarget = React.createRef<HTMLDivElement>(); private _headerRefs: SchemaColumnHeader[] = []; - private _eqHighlightColors: Array<[{r: number, g: number, b: number}, {r: number, g: number, b: number}]> = []; + private _eqHighlightColors: Array<[{ r: number; g: number; b: number }, { r: number; g: number; b: number }]> = []; + private _oldWheel: HTMLDivElement | null = null; constructor(props: SubCollectionViewProps) { 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]}} // 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 + const colors = (r: number, g: number, b: number):[{r:number,g:number,b:number},{r:number,g:number,b:number}] => ([{r, g, 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)); @@ -122,8 +123,8 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _highlightedCellsInfo: Array<[doc: Doc, field: string]> = []; @observable _cellHighlightColors: ObservableMap = new ObservableMap<string, string[]>(); @observable _containedDocs: Doc[] = []; //all direct children of the schema - @observable _referenceSelectMode: {enabled: boolean, currEditing: SchemaCellField | undefined} = {enabled: false, currEditing: undefined} - + @observable _referenceSelectMode: { enabled: boolean; currEditing: SchemaCellField | undefined } = { enabled: false, currEditing: undefined }; + // target HTMLelement portal for showing a popup menu to edit cell values. public get MenuTarget() { return this._menuTarget.current; @@ -217,15 +218,17 @@ export class CollectionSchemaView extends CollectionSubView() { true ); this._disposers.docdata = reaction( - () => DocListCast(this.dataDoc[this.fieldKey]), - (docs) => this._containedDocs = docs, - {fireImmediately: true} - ) + () => DocListCast(this.dataDoc[this.fieldKey]), + docs => (this._containedDocs = docs), + { fireImmediately: true } + ); this._disposers.sortHighlight = reaction( - () => [this.sortField, this._containedDocs, this._selectedDocs, this._highlightedCellsInfo], - () => {this.sortField && setTimeout(() => this.highlightSortedColumn())}, - {fireImmediately: true} - ) + () => [this.sortField, this._containedDocs, this._selectedDocs, this._highlightedCellsInfo], + () => { + this.sortField && setTimeout(() => this.highlightSortedColumn()); + }, + { fireImmediately: true } + ); } componentWillUnmount() { @@ -239,8 +242,8 @@ export class CollectionSchemaView extends CollectionSubView() { removeDoc = (doc: Doc) => { this.removeDocument(doc); - this._containedDocs = this._containedDocs.filter(d => d !== doc) - } + this._containedDocs = this._containedDocs.filter(d => d !== doc); + }; rowIndex = (doc: Doc) => this.docsWithDrag.docs.indexOf(doc); @@ -301,7 +304,9 @@ export class CollectionSchemaView extends CollectionSubView() { } break; case 'Backspace': { - undoable(() => {this._selectedDocs.forEach(d => this._containedDocs.includes(d) && this.removeDoc(d));}, 'delete schema row'); + undoable(() => { + this._selectedDocs.forEach(d => this._containedDocs.includes(d) && this.removeDoc(d)); + }, 'delete schema row'); break; } case 'Escape': { @@ -319,7 +324,7 @@ export class CollectionSchemaView extends CollectionSubView() { addRow = (doc: Doc | Doc[]) => this.addDocument(doc); @undoBatch - changeColumnKey = (index: number, newKey: string, defaultVal?: any) => { + changeColumnKey = (index: number, newKey: string, defaultVal?: FieldType) => { if (!this.documentKeys.includes(newKey)) this.addNewKey(newKey, defaultVal); const currKeys = this.columnKeys.slice(); // copy the column key array first, then change it. @@ -328,9 +333,10 @@ export class CollectionSchemaView extends CollectionSubView() { }; @undoBatch - addColumn = (index: number = 0, key?: string, defaultVal?: any) => { + addColumn = (index: number = 0, keyIn?: string, defaultVal?: FieldType) => { + let key = keyIn; if (key && !this.documentKeys.includes(key)) this.addNewKey(key, defaultVal); - + const newColWidth = this.tableWidth / (this.storedColumnWidths.length + 1); const currWidths = this.storedColumnWidths.slice(); currWidths.splice(index, 0, newColWidth); @@ -345,11 +351,11 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - addNewKey = (key: string, defaultVal: any) => { + addNewKey = (key: string, defaultVal: FieldType | undefined) => { this.childDocs.forEach(doc => { doc[DocData][key] = defaultVal; }); - } + }; @undoBatch removeColumn = (index: number) => { @@ -365,13 +371,13 @@ export class CollectionSchemaView extends CollectionSubView() { const currKeys = this.columnKeys.slice(); currKeys.splice(index, 1); - this.layoutDoc.schema_columnKeys = new List<string>(currKeys); + this.layoutDoc.schema_columnKeys = new List<string>(currKeys); this._colEles.splice(index, 1); }; @action - startResize = (e: any, index: number, rightSide: boolean) => { + startResize = (e: React.PointerEvent, index: number, rightSide: boolean) => { this._displayColumnWidths = this.storedColumnWidths; setupMoveUpEvents(this, e, moveEv => this.resizeColumn(moveEv, index, rightSide), this.finishResize, emptyFunction); }; @@ -384,8 +390,8 @@ export class CollectionSchemaView extends CollectionSubView() { let change = e.movementX; - if (rightSide && (index !== this._displayColumnWidths.length - 1)) { - growing = change < 0 ? index + 1: index; + if (rightSide && index !== this._displayColumnWidths.length - 1) { + growing = change < 0 ? index + 1 : index; shrinking = change < 0 ? index : index + 1; } else if (index !== 0) { growing = change < 0 ? index : index - 1; @@ -432,7 +438,7 @@ export class CollectionSchemaView extends CollectionSubView() { this.closeNewColumnMenu(); this._headerRefs.forEach(ref => ref.toggleEditing(false)); this._draggedColIndex = index; - this.setColDrag(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])); @@ -446,7 +452,7 @@ export class CollectionSchemaView extends CollectionSubView() { * @returns column index */ findColDropIndex = (mouseX: number) => { - const xOffset: number = this._props.ScreenToLocalTransform().inverse().transformPoint(0,0)[0] + CollectionSchemaView._rowMenuWidth; + const xOffset: number = this._props.ScreenToLocalTransform().inverse().transformPoint(0, 0)[0] + CollectionSchemaView._rowMenuWidth; let index: number | undefined; this.displayColumnWidths.reduce((total, curr, i) => { if (total <= mouseX && total + curr >= mouseX) { @@ -507,12 +513,7 @@ 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); - const cellEles = [ - colRef, - ...this.docsWithDrag.docs - .filter(doc => (i !== this._selectedCol || !this._selectedDocs.includes(doc)) && !sorted) - .map(doc => this._rowEles.get(doc).children[1].children[i]), - ]; + const cellEles = [colRef, ...this.docsWithDrag.docs.filter(doc => (i !== this._selectedCol || !this._selectedDocs.includes(doc)) && !sorted).map(doc => this._rowEles.get(doc).children[1].children[i])]; cellEles.forEach(ele => { if (sorted || this.highlightedCells.includes(ele)) return; ele.style.borderTop = ele === cellEles[0] ? edgeStyle : ''; @@ -533,14 +534,14 @@ export class CollectionSchemaView extends CollectionSubView() { 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) { + if (!(this._selectedDocs.includes(doc) && i === this._selectedCol) && !this.highlightedCells.includes(cell) && cell) { cell.style.borderLeft = ''; cell.style.borderRight = ''; cell.style.borderBottom = ''; } }); }); - } + }; /** * Applies a gradient highlight to a sorted column. The direction of the gradient depends @@ -552,10 +553,10 @@ export class CollectionSchemaView extends CollectionSubView() { let index = -1; const highlightColors: string[] = []; const rowCount: number = this._containedDocs.length + 1; - if (field || this.sortField){ + if (field || this.sortField) { index = this.columnKeys.indexOf(field || this.sortField); - const increment: number = 110/rowCount; - for (let i = 1; i <= rowCount; ++i){ + const increment: number = 110 / rowCount; + for (let i = 1; i <= rowCount; ++i) { const adjColor = ClientUtils.lightenRGB(16, 66, 230, increment * i); highlightColors.push(`solid 2px rgb(${adjColor[0]}, ${adjColor[1]}, ${adjColor[2]})`); } @@ -564,25 +565,20 @@ export class CollectionSchemaView extends CollectionSubView() { this._colEles.forEach((colRef, i) => { const highlight: boolean = i === index; const desc: boolean = descending || this.sortDesc; - const cellEles = [ - colRef, - ...this.docsWithDrag.docs - .filter(doc => (i !== this._selectedCol || !this._selectedDocs.includes(doc))) - .map(doc => this._rowEles.get(doc).children[1].children[i]), - ]; + const cellEles = [colRef, ...this.docsWithDrag.docs.filter(doc => i !== this._selectedCol || !this._selectedDocs.includes(doc)).map(doc => this._rowEles.get(doc).children[1].children[i])]; const cellCount = cellEles.length; - for (let ele = 0; ele < cellCount; ++ele){ + for (let ele = 0; ele < cellCount; ++ele) { const currCell = cellEles[ele]; if (this.highlightedCells.includes(currCell)) continue; - const style = highlight ? desc ? `${highlightColors[cellCount - 1 - ele]}` : `${highlightColors[ele]}` : ''; + const style = highlight ? (desc ? `${highlightColors[cellCount - 1 - ele]}` : `${highlightColors[ele]}`) : ''; currCell.style.borderLeft = style; currCell.style.borderRight = style; } - cellEles[0].style.borderTop = highlight ? desc ? `${highlightColors[cellCount - 1]}` : `${highlightColors[0]}` : ''; - if (!(this._selectedDocs.includes(this.docsWithDrag.docs[this.docsWithDrag.docs.length - 1]) && this._selectedCol === index) && !this.highlightedCells.includes(cellEles[cellCount - 1])) cellEles[cellCount - 1].style.borderBottom = highlight ? desc ? `${highlightColors[0]}` : `${highlightColors[cellCount - 1]}` : ''; + cellEles[0].style.borderTop = highlight ? (desc ? `${highlightColors[cellCount - 1]}` : `${highlightColors[0]}`) : ''; + if (!(this._selectedDocs.includes(this.docsWithDrag.docs[this.docsWithDrag.docs.length - 1]) && this._selectedCol === index) && !this.highlightedCells.includes(cellEles[cellCount - 1])) + cellEles[cellCount - 1].style.borderBottom = highlight ? (desc ? `${highlightColors[0]}` : `${highlightColors[cellCount - 1]}`) : ''; }); - - } + }; /** * Gets the html element representing a cell so that styles can be applied on it. @@ -594,35 +590,40 @@ export class CollectionSchemaView extends CollectionSubView() { const index = this.columnKeys.indexOf(fieldKey); const cell = this._rowEles.get(doc).children[1].children[index]; return cell; - } + }; /** * Given text in a cell, find references to other cells (for equations). * @param text the text in the cell - * @returns the html cell elements referenced in the text. + * @returns the html cell elements referenced in the text. */ findCellRefs = (text: string) => { const pattern = /(this|d(\d+))\.(\w+)/g; - interface Match { docRef: string; field: string; } + 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]; + const docRef = match[1] === 'this' ? match[1] : match[2]; matches.push({ docRef, field: match[3] }); } - const cells: Array<any> = []; - matches.forEach((match: Match) => { - const {docRef, field} = match; + const cells: [Doc, string][] = []; + matches.forEach((m: Match) => { + const { docRef, field } = m; const docView = DocumentManager.Instance.DocumentViews[Number(docRef)]; const doc = docView?.Document ?? undefined; - if (this.columnKeys.includes(field) && this._containedDocs.includes(doc)) {cells.push([doc, field])} - }) + if (this.columnKeys.includes(field) && this._containedDocs.includes(doc)) { + cells.push([doc, field]); + } + }); return cells; - } + }; /** * Determines whether the rows above or below a given row have been @@ -636,7 +637,7 @@ export class CollectionSchemaView extends CollectionSubView() { const selectedBelow: boolean = this._selectedDocs.includes(docs[index + 1]); const selectedAbove: boolean = this._selectedDocs.includes(docs[index - 1]); return [selectedAbove, selectedBelow]; - } + }; @action removeCellHighlights = () => { @@ -649,9 +650,10 @@ export class CollectionSchemaView extends CollectionSubView() { if (this.selectionOverlap(doc)[0]) cell.style.borderTop = ''; if (this.selectionOverlap(doc)[1]) cell.style.borderBottom = ''; } else cell.style.border = ''; - cell.style.backgroundColor = '';}); + cell.style.backgroundColor = ''; + }); this._highlightedCellsInfo = []; - } + }; restoreCellHighlights = () => { this._highlightedCellsInfo.forEach(info => { @@ -665,10 +667,10 @@ export class CollectionSchemaView extends CollectionSubView() { cell.style.borderRight = color; cell.style.borderBottom = color; }); - } + }; /** - * Highlights cells based on equation text in the cell currently being edited. + * Highlights cells based on equation text in the cell currently being edited. * Does not highlight selected cells (that's done directly in SchemaTableCell). * @param text the equation */ @@ -682,7 +684,7 @@ export class CollectionSchemaView extends CollectionSubView() { const info = this._highlightedCellsInfo[i]; const color = this._eqHighlightColors[i % 10]; const colorStrings = [`solid 2px rgb(${color[0].r}, ${color[0].g}, ${color[0].b})`, `rgb(${color[1].r}, ${color[1].g}, ${color[1].b})`]; - const doc = info[0]; + const doc = info[0]; const field = info[1]; const key = `${doc[Id]}_${field}`; const cell = this.getCellElement(doc, field); @@ -690,7 +692,7 @@ export class CollectionSchemaView extends CollectionSubView() { cell.style.border = colorStrings[0]; cell.style.backgroundColor = colorStrings[1]; } - } + }; //Used in SchemaRowBox @action @@ -718,7 +720,6 @@ export class CollectionSchemaView extends CollectionSubView() { this.deselectAllCells(); }; - selectRow = (doc: Doc, lastSelected: Doc) => { const index = this.rowIndex(doc); const lastSelectedRow = this.rowIndex(lastSelected); @@ -737,12 +738,12 @@ export class CollectionSchemaView extends CollectionSubView() { 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; + const refToAdd = `d${docIndex}.${field}`; + const editedField = this._referenceSelectMode.currEditing ? (this._referenceSelectMode.currEditing as SchemaCellField) : null; editedField?.insertText(refToAdd, true); editedField?.setupRefSelect(false); return; - } + }; @action selectCell = (doc: Doc, col: number, shiftKey: boolean, ctrlKey: boolean) => { @@ -787,7 +788,9 @@ export class CollectionSchemaView extends CollectionSubView() { @action onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.columnDragData) { - setTimeout(() => {this.setColDrag(false);}); + setTimeout(() => { + this.setColDrag(false); + }); e.stopPropagation(); return true; } @@ -849,9 +852,9 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - setKey = (key: string, defaultVal?: any, index?: number) => { + setKey = (key: string, defaultVal?: string, index?: number) => { if (this.columnKeys.includes(key)) return; - + if (this._makeNewColumn) { this.addColumn(this.columnKeys.indexOf(key), key, defaultVal); this._makeNewColumn = false; @@ -861,14 +864,14 @@ export class CollectionSchemaView extends CollectionSubView() { }; /** - * Used in SchemaRowBox to set - * @param key - * @param value - * @returns + * Used in SchemaRowBox to set + * @param key + * @param value + * @returns */ 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)); + 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; }; @@ -912,34 +915,36 @@ 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 ?? [] : []; + 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', + description: 'Sort A-Z', event: () => { - this.setColumnSort(undefined); + this.setColumnSort(undefined); const field = this.columnKeys[index]; this._containedDocs = this.sortDocs(field, false); setTimeout(() => { this.highlightSortedColumn(field, false); - setTimeout(() => this.highlightSortedColumn(), 480); + setTimeout(() => this.highlightSortedColumn(), 480); }, 20); - }, - icon: 'arrow-down-a-z',}); + }, + icon: 'arrow-down-a-z', + }); sortOptions.push({ - description: 'Sort Z-A', + description: 'Sort Z-A', event: () => { - this.setColumnSort(undefined); + this.setColumnSort(undefined); const field = this.columnKeys[index]; this._containedDocs = this.sortDocs(field, true); setTimeout(() => { this.highlightSortedColumn(field, true); - setTimeout(() => this.highlightSortedColumn(), 480); + setTimeout(() => this.highlightSortedColumn(), 480); }, 20); - }, - icon: 'arrow-up-z-a'}); + }, + icon: 'arrow-up-z-a', + }); sortOptions.push({ description: 'Persistent Sort A-Z', event: () => { @@ -964,7 +969,7 @@ export class CollectionSchemaView extends CollectionSubView() { } }, icon: fieldSortedDesc ? 'lock' : 'lock-open'}); // prettier-ignore - + cm.addItem({ description: `Change field`, event: () => this.openNewColumnMenu(index, false), @@ -975,12 +980,12 @@ export class CollectionSchemaView extends CollectionSubView() { event: () => this.openFilterMenu(index), icon: 'filter', }); - cm.addItem({ - description: 'Sort column', - addDivider: false, - noexpand: true, - subitems: sortOptions, - icon: 'sort' + cm.addItem({ + description: 'Sort column', + addDivider: false, + noexpand: true, + subitems: sortOptions, + icon: 'sort', }); cm.addItem({ description: 'Add column to left', @@ -1068,7 +1073,7 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get renderColumnMenu() { const x = this._columnMenuIndex! === -1 ? 0 : this.displayColumnWidths.reduce((total, curr, index) => total + (index < this._columnMenuIndex! ? curr : 0), CollectionSchemaView._rowMenuWidth); return ( - <div className="schema-column-menu" style={{ left: x, maxWidth: `${Math.max(this._colEles[this._columnMenuIndex ?? 0].offsetWidth, 150)}px` }}> + <div className="schema-column-menu" style={{ left: x, maxWidth: `${Math.max(this._colEles[this._columnMenuIndex ?? 0].offsetWidth, 150)}px` }}> {this.keysDropdown} </div> ); @@ -1095,13 +1100,7 @@ export class CollectionSchemaView extends CollectionSubView() { } return ( <div key={key} className="schema-filter-option"> - <input - type="checkbox" - onPointerDown={e => e.stopPropagation()} - onClick={e => e.stopPropagation()} - onChange={e => Doc.setDocFilter(this.Document, columnKey, key, e.target.checked ? 'check' : 'remove')} - checked={bool} - /> + <input type="checkbox" onPointerDown={e => e.stopPropagation()} onClick={e => e.stopPropagation()} onChange={e => Doc.setDocFilter(this.Document, columnKey, key, e.target.checked ? 'check' : 'remove')} checked={bool} /> <span style={{ paddingLeft: 4 }}>{key}</span> </div> ); @@ -1111,7 +1110,7 @@ export class CollectionSchemaView extends CollectionSubView() { @computed get renderFilterMenu() { const x = this.displayColumnWidths.reduce((total, curr, index) => total + (index < this._filterColumnIndex! ? curr : 0), CollectionSchemaView._rowMenuWidth); return ( - <div className="schema-filter-menu" style={{ left: x, maxWidth: `${Math.max(this._colEles[this._columnMenuIndex ?? 0].offsetWidth, 150)}px`}}> + <div className="schema-filter-menu" style={{ left: x, maxWidth: `${Math.max(this._colEles[this._columnMenuIndex ?? 0].offsetWidth, 150)}px` }}> <input className="schema-filter-input" type="text" value={this._filterSearchValue} onKeyDown={this.onFilterKeyDown} onChange={this.updateFilterSearch} onPointerDown={e => e.stopPropagation()} /> {this.renderFilterOptions} <div @@ -1129,13 +1128,13 @@ export class CollectionSchemaView extends CollectionSubView() { @action setColDrag = (beingDragged: boolean) => { this._colBeingDragged = beingDragged; !beingDragged && this.removeDragHighlight(); - } + }; @action updateMouseCoordinates = (e: React.PointerEvent<HTMLDivElement>) => { 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<HTMLDivElement>) => { @@ -1158,9 +1157,9 @@ export class CollectionSchemaView extends CollectionSubView() { /** * Gets docs contained by collections within the schema. Currently defunct. - * @param doc - * @param displayed - * @returns + * @param doc + * @param displayed + * @returns */ // subCollectionDocs = (doc: Doc, displayed: boolean) => { // const childDocs = DocListCast(doc[Doc.LayoutFieldKey(doc)]); @@ -1203,8 +1202,7 @@ export class CollectionSchemaView extends CollectionSubView() { subDocs.forEach(t => { const docFieldKey = Doc.LayoutFieldKey(t); const isSubDocAnnotatable = t[docFieldKey] instanceof List && !(t[docFieldKey] as List<Doc>)?.some(ele => !(ele instanceof Doc)); - notFiltered = - notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!childDocFilters.length && !childFiltersByRanges.length) || DocUtils.FilterDocs([t], childDocFilters, childFiltersByRanges, d).length)); + notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!childDocFilters.length && !childFiltersByRanges.length) || DocUtils.FilterDocs([t], childDocFilters, childFiltersByRanges, d).length)); DocListCast(t[isSubDocAnnotatable ? docFieldKey + '_annotations' : docFieldKey]).forEach(newdoc => newarray.push(newdoc)); isSubDocAnnotatable && DocListCast(t[docFieldKey + '_sidebar']).forEach(newdoc => newarray.push(newdoc)); }); @@ -1231,19 +1229,19 @@ export class CollectionSchemaView extends CollectionSubView() { // docsFromChildren = docsFromChildren.concat(docsNotAlreadyDisplayed); // }); - return this.filteredDocs;; + return this.filteredDocs; } /** - * Sorts docs first alphabetically and then numerically. + * Sorts docs first alphabetically and then numerically. * @param field the column being sorted * @param desc whether the sort is ascending or descending * @param persistent whether the sort is applied persistently or is one-shot - * @returns + * @returns */ sortDocs = (field: string, desc: boolean, persistent?: boolean) => { const numbers: Doc[] = []; - const strings: Doc[] = []; + const strings: Doc[] = []; this.docs.forEach(doc => { if (!isNaN(Number(Field.toString(doc[field] as FieldType)))) numbers.push(doc); @@ -1253,25 +1251,26 @@ export class CollectionSchemaView extends CollectionSubView() { const sortedNums = numbers.sort((numOne, numTwo) => { const numA = Number(Field.toString(numOne[field] as FieldType)); const numB = Number(Field.toString(numTwo[field] as FieldType)); - return desc? numA - numB : numB - numA; + return desc ? numA - numB : numB - numA; }); - const collator = new Intl.Collator(undefined, {sensitivity: 'base'}); + const collator = new Intl.Collator(undefined, { sensitivity: 'base' }); let sortedStrings; - if (!desc) {sortedStrings = strings.slice().sort((docA, docB) => collator.compare(Field.toString(docA[field] as FieldType), Field.toString(docB[field] as FieldType))); + if (!desc) { + sortedStrings = strings.slice().sort((docA, docB) => collator.compare(Field.toString(docA[field] as FieldType), Field.toString(docB[field] as FieldType))); } else sortedStrings = strings.slice().sort((docB, docA) => collator.compare(Field.toString(docA[field] as FieldType), Field.toString(docB[field] as FieldType))); const sortedDocs = desc ? sortedNums.concat(sortedStrings) : sortedStrings.concat(sortedNums); if (!persistent) this._containedDocs = sortedDocs; return sortedDocs; - } - + }; + /** * Returns all docs minus those currently being dragged by the user. */ @computed get docsWithDrag() { let docs = this.docs.slice(); - if (this.sortField){ + if (this.sortField) { const field = StrCast(this.layoutDoc.sortField); const desc = BoolCast(this.layoutDoc.sortDesc); // is this an ascending or descending sort docs = this.sortDocs(field, desc, true); @@ -1290,13 +1289,17 @@ export class CollectionSchemaView extends CollectionSubView() { previewWidthFunc = () => this.previewWidth; onPassiveWheel = (e: WheelEvent) => e.stopPropagation(); displayedDocsFunc = () => this.docsWithDrag.docs; - _oldWheel: any; render() { return ( - <div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} - onDrop={this.onExternalDrop.bind(this)} - onPointerMove={e => this.onPointerMove(e)} - onPointerDown={() => {this.closeNewColumnMenu(); this.setColDrag(false)}}> + <div + className="collectionSchemaView" + ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} + onDrop={this.onExternalDrop.bind(this)} + onPointerMove={e => this.onPointerMove(e)} + onPointerDown={() => { + this.closeNewColumnMenu(); + this.setColDrag(false); + }}> <div ref={this._menuTarget} style={{ background: 'red', top: 0, left: 0, position: 'absolute', zIndex: 10000 }} /> <div className="schema-table" @@ -1310,30 +1313,29 @@ export class CollectionSchemaView extends CollectionSubView() { <div className="schema-header-row" style={{ height: this.rowHeightFunc() }}> <div className="row-menu" style={{ width: CollectionSchemaView._rowMenuWidth }}> <IconButton - tooltip="Add a new key" - icon={ <FontAwesomeIcon icon="plus" size='lg'/>} - size={Size.XSMALL} - color={'black'} - onPointerDown={e => - setupMoveUpEvents( - this, - e, - returnFalse, - emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - this.addColumn() - }, 'add key to schema') - ) - } + tooltip="Add a new key" + icon={<FontAwesomeIcon icon="plus" size="lg" />} + size={Size.XSMALL} + color={'black'} + onPointerDown={e => + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + undoable(clickEv => { + clickEv.stopPropagation(); + this.addColumn(); + }, 'add key to schema') + ) + } /> </div> {this.columnKeys.map((key, index) => ( <SchemaColumnHeader - // eslint-disable-next-line react/no-array-index-key //cleanupField={this.cleanupComputedField} ref={r => r && this._headerRefs.push(r)} - keysDropdown={(this.keysDropdown)} + keysDropdown={this.keysDropdown} schemaView={this} columnWidth={() => CollectionSchemaView._minColWidth} //TODO: update Document={this.Document} @@ -1445,7 +1447,6 @@ class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaV return ( <DocumentView key={this._props.doc[Id]} - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props.schema._props} containerViewPath={this._props.schema.childContainerViewPath} LayoutTemplate={this._props.schema._props.childLayoutTemplate} @@ -1498,4 +1499,4 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP </div> ); } -}
\ No newline at end of file +} |
