aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/collectionSchema/CollectionSchemaView.tsx')
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx327
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
+}