aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx1077
1 files changed, 215 insertions, 862 deletions
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 18a53541d..4f87420d2 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -68,6 +68,28 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@observable pointerY: number = 0;
@computed get menuCoordinates() { return this.props.ScreenToLocalTransform().transformPoint(this.pointerX, this.pointerY); }
+ @computed get columns() {
+ return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []);
+ }
+ set columns(columns: SchemaHeaderField[]) {
+ this.props.Document.schemaColumns = new List<SchemaHeaderField>(columns);
+ }
+
+ get documentKeys() {
+ const docs = this.childDocs;
+ const keys: { [key: string]: boolean } = {};
+ // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields.
+ // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be
+ // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked.
+ // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu
+ // is displayed (unlikely) it won't show up until something else changes.
+ //TODO Types
+ untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false))));
+
+ this.columns.forEach(key => keys[key.heading] = true);
+ return Array.from(Object.keys(keys));
+ }
+
@observable col: any = "";
@computed get possibleKeys() { return this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1); }
@@ -77,16 +99,18 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@observable private _isOpen: boolean = false;
@observable private _node: HTMLDivElement | null = null;
+ @observable _headerIsEditing: boolean = false;
+
componentDidMount() {
document.addEventListener("pointerdown", this.detectClick);
- document.addEventListener("keydown", this.onKeyDown);
}
componentWillUnmount() {
document.removeEventListener("pointerdown", this.detectClick);
- document.removeEventListener("keydown", this.onKeyDown);
}
+ @action setHeaderIsEditing = (isEditing: boolean) => this._headerIsEditing = isEditing;
+
detectClick = (e: PointerEvent): void => {
if (this._node && this._node.contains(e.target as Node)) {
} else {
@@ -101,6 +125,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
this.setHeaderIsEditing(this._isOpen);
}
+
+
+
changeColumnType = (type: ColumnType, col: any): void => {
this.setColumnType(col, type);
}
@@ -113,6 +140,43 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
this.setColumnColor(col, color);
}
+ @undoBatch
+ setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
+ if (columnTypes.get(columnField.heading)) return;
+
+ const columns = this.columns;
+ const index = columns.indexOf(columnField);
+ if (index > -1) {
+ columnField.setType(NumCast(type));
+ columns[index] = columnField;
+ this.columns = columns;
+ }
+ }
+
+ @undoBatch
+ setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
+ const columns = this.columns;
+ const index = columns.indexOf(columnField);
+ if (index > -1) {
+ columnField.setColor(color);
+ columns[index] = columnField;
+ this.columns = columns; // need to set the columns to trigger rerender
+ }
+ }
+
+ @undoBatch
+ @action
+ setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
+ const columns = this.columns;
+ const index = columns.findIndex(c => c.heading === columnField.heading);
+ const column = columns[index];
+ column.setDesc(descending);
+ columns[index] = column;
+ this.columns = columns;
+ }
+
+
+
@action
setNode = (node: HTMLDivElement): void => {
if (node) {
@@ -209,6 +273,35 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
);
}
+ @undoBatch
+ @action
+ changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
+ const columns = this.columns;
+ if (columns === undefined) {
+ this.columns = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
+ } else {
+ if (addNew) {
+ columns.push(new SchemaHeaderField(newKey, "f1efeb"));
+ this.columns = columns;
+ } else {
+ const index = columns.map(c => c.heading).indexOf(oldKey);
+ if (index > -1) {
+ const column = columns[index];
+ column.setHeading(newKey);
+ columns[index] = column;
+ this.columns = columns;
+ }
+ }
+ }
+ }
+
+ @action
+ openHeader = (col: any, menu: any) => {
+ this.menuContent = menu;
+ this.col = col;
+ this.headerOpen = !this.headerOpen;
+ }
+
renderContent = (col: any) => {
return (
<div className="collectionSchema-header-menuOptions">
@@ -238,313 +331,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
);
}
-
- //anchorPoints.TOP_CENTER
-
- @computed get renderMenu() {
- return (
- <div className="collectionSchema-header-menu" ref={this.setNode}
- style={{
- position: "absolute", background: "white",
- transform: `translate(${this.menuCoordinates[0]}px, ${this.menuCoordinates[1] - 150}px)`
- }}>
- {/* <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderContent(this.col)}>
- <div className="collectionSchema-header-toggler" onClick={() => this.toggleIsOpen()}>{this.menuContent}</div>
- </ Flyout > */}
- {this.renderContent(this.col)}
- </div>
- );
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- // ADDED START HEREE
- //
- //
- //
-
- @observable _headerIsEditing: boolean = false;
- @observable _cellIsEditing: boolean = false;
- @observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 };
- @observable _openCollections: Array<string> = [];
-
- @observable _showDoc: Doc | undefined;
- @observable _showDataDoc: any = "";
- @observable _showDocPos: number[] = [];
-
- @computed get columns() {
- return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []);
- }
- set columns(columns: SchemaHeaderField[]) {
- this.props.Document.schemaColumns = new List<SchemaHeaderField>(columns);
- }
-
- // @computed get childDocs() {
- // if (this.childDocs) return this.childDocs;
-
- // const doc = this.props.DataDoc ? this.props.DataDoc : this.props.Document;
- // return DocListCast(doc[this.props.fieldKey]);
- // }
-
- set childDocs(docs: Doc[]) {
- const doc = this.props.DataDoc ? this.props.DataDoc : this.props.Document;
- doc[this.props.fieldKey] = new List<Doc>(docs);
- }
-
- @computed get textWrappedRows() {
- return Cast(this.props.Document.textwrappedSchemaRows, listSpec("string"), []);
- }
- set textWrappedRows(textWrappedRows: string[]) {
- this.props.Document.textwrappedSchemaRows = new List<string>(textWrappedRows);
- }
-
- @computed get resized(): { id: string, value: number }[] {
- return this.columns.reduce((resized, shf) => {
- (shf.width > -1) && resized.push({ id: shf.heading, value: shf.width });
- return resized;
- }, [] as { id: string, value: number }[]);
- }
- @computed get sorted(): SortingRule[] {
- return this.columns.reduce((sorted, shf) => {
- shf.desc && sorted.push({ id: shf.heading, desc: shf.desc });
- return sorted;
- }, [] as SortingRule[]);
- }
-
- @action
- openHeader = (col: any, menu: any) => {
- this.menuContent = menu;
- this.col = col;
- this.headerOpen = !this.headerOpen;
- }
-
- @computed get tableColumns(): Column<Doc>[] {
- const columns: Column<Doc>[] = [];
- const tableIsFocused = this.isFocused(this.props.Document);
- const focusedRow = this._focusedCell.row;
- const focusedCol = this._focusedCell.col;
- const isEditable = !this._headerIsEditing;
-
- if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) {
- columns.push(
- {
- expander: true,
- Header: "",
- width: 30,
- Expander: (rowInfo) => {
- if (rowInfo.original.type === "collection") {
- if (rowInfo.isExpanded) return <div className="collectionSchemaView-expander" onClick={() => this.onCloseCollection(rowInfo.original)}><FontAwesomeIcon icon={"sort-up"} size="sm" /></div>;
- if (!rowInfo.isExpanded) return <div className="collectionSchemaView-expander" onClick={() => this.onExpandCollection(rowInfo.original)}><FontAwesomeIcon icon={"sort-down"} size="sm" /></div>;
- } else {
- return null;
- }
- }
- }
- );
- }
-
- const cols = this.columns.map(col => {
-
- const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
- this.getColumnType(col) === ColumnType.Boolean ? "check-square" : this.getColumnType(col) === ColumnType.Doc ? "file" :
- this.getColumnType(col) === ColumnType.Image ? "image" : this.getColumnType(col) === ColumnType.List ? "list-ul" : "align-justify";
-
- // this.menuContent = <div><FontAwesomeIcon icon={icon} size="sm" />{col.heading}</div>;
-
- const menuContent = <div><FontAwesomeIcon icon={icon} size="sm" />{col.heading}</div>;
-
- // this.col = col;
-
- const header =
- <div className="collectionSchemaView-header"
- onClick={e => { this.openHeader(col, menuContent); }}
- style={{ background: col.color }}>
- {menuContent}
- </div>;
-
-
- // <CollectionSchemaHeader
- // keyValue={col}
- // possibleKeys={possibleKeys}
- // existingKeys={this.columns.map(c => c.heading)}
- // keyType={this.getColumnType(col)}
- // typeConst={columnTypes.get(col.heading) !== undefined}
- // onSelect={this.changeColumns}
- // setIsEditing={this.setHeaderIsEditing}
- // deleteColumn={this.deleteColumn}
- // setColumnType={this.setColumnType}
- // setColumnSort={this.setColumnSort}
- // setColumnColor={this.setColumnColor}
- // />;
-
-
- return {
- Header: <MovableColumn columnRenderer={header} columnValue={col} allColumns={this.columns} reorderColumns={this.reorderColumns} ScreenToLocalTransform={this.props.ScreenToLocalTransform} />,
- accessor: (doc: Doc) => doc ? doc[col.heading] : 0,
- id: col.heading,
- Cell: (rowProps: CellInfo) => {
- const rowIndex = rowProps.index;
- const columnIndex = this.columns.map(c => c.heading).indexOf(rowProps.column.id!);
- const isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused;
-
- const props: CellProps = {
- row: rowIndex,
- col: columnIndex,
- rowProps: rowProps,
- isFocused: isFocused,
- changeFocusedCellByIndex: this.changeFocusedCellByIndex,
- CollectionView: this.props.CollectionView,
- ContainingCollection: this.props.ContainingCollectionView,
- Document: this.props.Document,
- fieldKey: this.props.fieldKey,
- renderDepth: this.props.renderDepth,
- addDocTab: this.props.addDocTab,
- pinToPres: this.props.pinToPres,
- moveDocument: this.props.moveDocument,
- setIsEditing: this.setCellIsEditing,
- isEditable: isEditable,
- setPreviewDoc: this.setPreviewDoc,
- setComputed: this.setComputed,
- getField: this.getField,
- showDoc: this.showDoc,
- };
-
- const colType = this.getColumnType(col);
- if (colType === ColumnType.Number) return <CollectionSchemaNumberCell {...props} />;
- if (colType === ColumnType.String) return <CollectionSchemaStringCell {...props} />;
- if (colType === ColumnType.Boolean) return <CollectionSchemaCheckboxCell {...props} />;
- if (colType === ColumnType.Doc) return <CollectionSchemaDocCell {...props} />;
- if (colType === ColumnType.Image) return <CollectionSchemaImageCell {...props} />;
- if (colType === ColumnType.List) return <CollectionSchemaListCell {...props} />;
- return <CollectionSchemaCell {...props} />;
- },
- minWidth: 200,
- };
- });
- columns.push(...cols);
-
- columns.push({
- Header: <CollectionSchemaAddColumnHeader createColumn={this.createColumn} />,
- accessor: (doc: Doc) => 0,
- id: "add",
- Cell: (rowProps: CellInfo) => <></>,
- width: 28,
- resizable: false
- });
- return columns;
- }
-
- tableAddDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
- return Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
- }
-
- private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
- return !rowInfo ? {} : {
- ScreenToLocalTransform: this.props.ScreenToLocalTransform,
- addDoc: this.tableAddDoc,
- removeDoc: this.props.removeDocument,
- rowInfo,
- rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.isFocused(this.props.Document),
- textWrapRow: this.toggleTextWrapRow,
- rowWrapped: this.textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1,
- dropAction: StrCast(this.props.Document.childDropAction),
- addDocTab: this.props.addDocTab
- };
- }
-
- private getTdProps: ComponentPropsGetterR = (state, rowInfo, column, instance) => {
- if (!rowInfo || column) return {};
-
- const row = rowInfo.index;
- //@ts-ignore
- const col = this.columns.map(c => c.heading).indexOf(column!.id);
- const isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.isFocused(this.props.Document);
- // TODO: editing border doesn't work :(
- return {
- style: {
- border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb"
- }
- };
- }
-
- @action
- onCloseCollection = (collection: Doc): void => {
- const index = this._openCollections.findIndex(col => col === collection[Id]);
- if (index > -1) this._openCollections.splice(index, 1);
- }
-
- @action onExpandCollection = (collection: Doc) => this._openCollections.push(collection[Id]);
- @action setCellIsEditing = (isEditing: boolean) => this._cellIsEditing = isEditing;
- @action setHeaderIsEditing = (isEditing: boolean) => this._headerIsEditing = isEditing;
-
- @action
- onPointDown = (e: React.PointerEvent): void => {
- this.setFocused(this.props.Document);
- if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected(true)) {
- e.stopPropagation();
- }
- this.pointerY = e.screenY;
- this.pointerX = e.screenX;
- this.headerOpen = false;
- }
-
- @action
- onKeyDown = (e: KeyboardEvent): void => {
- if (!this._cellIsEditing && !this._headerIsEditing && this.isFocused(this.props.Document)) {// && this.props.isSelected(true)) {
- const direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
- this._focusedCell = this.changeFocusedCellByDirection(direction, this._focusedCell.row, this._focusedCell.col);
-
- const pdoc = FieldValue(this.childDocs[this._focusedCell.row]);
- pdoc && this.setPreviewDoc(pdoc);
- }
- }
-
- changeFocusedCellByDirection = (direction: string, curRow: number, curCol: number) => {
- switch (direction) {
- case "tab": return { row: (curRow + 1 === this.childDocs.length ? 0 : curRow + 1), col: curCol + 1 === this.columns.length ? 0 : curCol + 1 };
- case "right": return { row: curRow, col: curCol + 1 === this.columns.length ? curCol : curCol + 1 };
- case "left": return { row: curRow, col: curCol === 0 ? curCol : curCol - 1 };
- case "up": return { row: curRow === 0 ? curRow : curRow - 1, col: curCol };
- case "down": return { row: curRow + 1 === this.childDocs.length ? curRow : curRow + 1, col: curCol };
- }
- return this._focusedCell;
- }
-
- @action
- changeFocusedCellByIndex = (row: number, col: number): void => {
- if (this._focusedCell.row !== row || this._focusedCell.col !== col) {
- this._focusedCell = { row: row, col: col };
- }
- this.setFocused(this.props.Document);
- }
-
- @undoBatch
- createRow = () => {
- this.props.addDocument(Docs.Create.TextDocument("", { title: "", _width: 100, _height: 30 }));
- }
-
- @undoBatch
- @action
- createColumn = () => {
- let index = 0;
- let found = this.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
- while (found) {
- index++;
- found = this.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
- }
- this.columns.push(new SchemaHeaderField(`New field ${index ? "(" + index + ")" : ""}`, "#f1efeb"));
- }
-
@undoBatch
@action
deleteColumn = (key: string) => {
@@ -560,284 +346,26 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
}
}
- @undoBatch
- @action
- changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
- const columns = this.columns;
- if (columns === undefined) {
- this.columns = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
- } else {
- if (addNew) {
- columns.push(new SchemaHeaderField(newKey, "f1efeb"));
- this.columns = columns;
- } else {
- const index = columns.map(c => c.heading).indexOf(oldKey);
- if (index > -1) {
- const column = columns[index];
- column.setHeading(newKey);
- columns[index] = column;
- this.columns = columns;
- }
- }
- }
- }
-
- getColumnType = (column: SchemaHeaderField): ColumnType => {
- // added functionality to convert old column type stuff to new column type stuff -syip
- if (column.type && column.type !== 0) {
- return column.type;
- }
- if (columnTypes.get(column.heading)) {
- column.type = columnTypes.get(column.heading)!;
- return columnTypes.get(column.heading)!;
- }
- const typesDoc = FieldValue(Cast(this.props.Document.schemaColumnTypes, Doc));
- if (!typesDoc) {
- column.type = ColumnType.Any;
- return ColumnType.Any;
- }
- column.type = NumCast(typesDoc[column.heading]);
- return NumCast(typesDoc[column.heading]);
- }
-
- @undoBatch
- setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
- if (columnTypes.get(columnField.heading)) return;
-
- const columns = this.columns;
- const index = columns.indexOf(columnField);
- if (index > -1) {
- columnField.setType(NumCast(type));
- columns[index] = columnField;
- this.columns = columns;
- }
- }
-
- @undoBatch
- setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
- const columns = this.columns;
- const index = columns.indexOf(columnField);
- if (index > -1) {
- columnField.setColor(color);
- columns[index] = columnField;
- this.columns = columns; // need to set the columns to trigger rerender
- }
- }
-
- @action
- setColumns = (columns: SchemaHeaderField[]) => this.columns = columns
-
- @undoBatch
- reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
- const columns = [...columnsValues];
- const oldIndex = columns.indexOf(toMove);
- const relIndex = columns.indexOf(relativeTo);
- const newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex;
-
- if (oldIndex === newIndex) return;
-
- columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]);
- this.columns = columns;
- }
-
- @undoBatch
- @action
- setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
- const columns = this.columns;
- const index = columns.findIndex(c => c.heading === columnField.heading);
- const column = columns[index];
- column.setDesc(descending);
- columns[index] = column;
- this.columns = columns;
- }
-
- get documentKeys() {
- const docs = this.childDocs;
- const keys: { [key: string]: boolean } = {};
- // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields.
- // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be
- // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked.
- // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu
- // is displayed (unlikely) it won't show up until something else changes.
- //TODO Types
- untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false))));
-
- this.columns.forEach(key => keys[key.heading] = true);
- return Array.from(Object.keys(keys));
- }
-
- @undoBatch
- @action
- toggleTextwrap = async () => {
- const textwrappedRows = Cast(this.props.Document.textwrappedSchemaRows, listSpec("string"), []);
- if (textwrappedRows.length) {
- this.props.Document.textwrappedSchemaRows = new List<string>([]);
- } else {
- const docs = DocListCast(this.props.Document[this.props.fieldKey]);
- const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]);
- this.props.Document.textwrappedSchemaRows = new List<string>(allRows);
- }
- }
-
- @action
- toggleTextWrapRow = (doc: Doc): void => {
- const textWrapped = this.textWrappedRows;
- const index = textWrapped.findIndex(id => doc[Id] === id);
-
- index > -1 ? textWrapped.splice(index, 1) : textWrapped.push(doc[Id]);
-
- this.textWrappedRows = textWrapped;
- }
-
- @computed
- get reactTable() {
- const children = this.childDocs;
- const hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false);
- const expandedRowsList = this._openCollections.map(col => children.findIndex(doc => doc[Id] === col).toString());
- const expanded = {};
- //@ts-ignore
- expandedRowsList.forEach(row => expanded[row] = true);
- const rerender = [...this.textWrappedRows]; // TODO: get component to rerender on text wrap change without needign to console.log :((((
-
- return <ReactTable
- style={{ position: "relative" }}
- data={children}
- page={0}
- pageSize={children.length}
- showPagination={false}
- columns={this.tableColumns}
- getTrProps={this.getTrProps}
- getTdProps={this.getTdProps}
- sortable={false}
- TrComponent={MovableRow}
- sorted={this.sorted}
- expanded={expanded}
- resized={this.resized}
- onResizedChange={this.onResizedChange}
- SubComponent={!hasCollectionChild ? undefined : row => (row.original.type !== "collection") ? (null) :
- <div className="reactTable-sub">{this.renderSchemaTable(row.original, undefined, undefined)}</div>}
- //<div className="reactTable-sub"><SchemaTable {...this.props} Document={row.original} dataDoc={undefined} childDocs={undefined} /></div>}
-
- />;
- }
-
- onResizedChange = (newResized: Resize[], event: any) => {
- const columns = this.columns;
- newResized.forEach(resized => {
- const index = columns.findIndex(c => c.heading === resized.id);
- const column = columns[index];
- column.setWidth(resized.value);
- columns[index] = column;
- });
- this.columns = columns;
- }
-
- onContextMenu = (e: React.MouseEvent): void => {
- if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
- // ContextMenu.Instance.addItem({ description: "Make DB", event: this.makeDB, icon: "table" });
- ContextMenu.Instance.addItem({ description: "Toggle text wrapping", event: this.toggleTextwrap, icon: "table" });
- }
- }
-
- getField = (row: number, col?: number) => {
- const docs = this.childDocs;
-
- row = row % docs.length;
- while (row < 0) row += docs.length;
- const columns = this.columns;
- const doc = docs[row];
- if (col === undefined) {
- return doc;
- }
- if (col >= 0 && col < columns.length) {
- const column = this.columns[col].heading;
- return doc[column];
- }
- return undefined;
- }
-
- createTransformer = (row: number, col: number): Transformer => {
- const self = this;
- const captures: { [name: string]: Field } = {};
-
- const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
- return root => {
- function visit(node: ts.Node) {
- node = ts.visitEachChild(node, visit, context);
- if (ts.isIdentifier(node)) {
- const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
- const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
- if (isntPropAccess && isntPropAssign) {
- if (node.text === "$r") {
- return ts.createNumericLiteral(row.toString());
- } else if (node.text === "$c") {
- return ts.createNumericLiteral(col.toString());
- } else if (node.text === "$") {
- if (ts.isCallExpression(node.parent)) {
- // captures.doc = self.props.Document;
- // captures.key = self.props.fieldKey;
- }
- }
- }
- }
-
- return node;
- }
- return ts.visitNode(root, visit);
- };
- };
-
- // const getVars = () => {
- // return { capturedVariables: captures };
- // };
-
- return { transformer, /*getVars*/ };
- }
-
- setComputed = (script: string, doc: Doc, field: string, row: number, col: number): boolean => {
- script =
- `const $ = (row:number, col?:number) => {
- if(col === undefined) {
- return (doc as any)[key][row + ${row}];
- }
- return (doc as any)[key][row + ${row}][(doc as any).schemaColumns[col + ${col}].heading];
- }
- return ${script}`;
- const compiled = CompileScript(script, { params: { this: Doc.name }, capturedVariables: { doc: this.props.Document, key: this.props.fieldKey }, typecheck: false, transformer: this.createTransformer(row, col) });
- if (compiled.compiled) {
- doc[field] = new ComputedField(compiled);
- return true;
- }
- return false;
- }
-
- @action
- showDoc = (doc: Doc | undefined, dataDoc?: Doc, screenX?: number, screenY?: number) => {
- this._showDoc = doc;
- if (dataDoc && screenX && screenY) {
- this._showDocPos = this.props.ScreenToLocalTransform().transformPoint(screenX, screenY);
- }
- }
-
- onOpenClick = () => {
- if (this._showDoc) {
- this.props.addDocTab(this._showDoc, "onRight");
- }
- }
-
getPreviewTransform = (): Transform => {
- return this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth, - this.borderWidth);
+ return this.props.ScreenToLocalTransform().translate(- this.borderWidth - 4 - this.tableWidth, - this.borderWidth);
}
+ //anchorPoints.TOP_CENTER
-
- // ADDED ENDS HERE
- //
- //
-
-
-
-
+ @computed get renderMenu() {
+ return (
+ <div className="collectionSchema-header-menu" ref={this.setNode}
+ style={{
+ position: "absolute", background: "white",
+ transform: `translate(${this.menuCoordinates[0]}px, ${this.menuCoordinates[1] - 150}px)`
+ }}>
+ {/* <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderContent(this.col)}>
+ <div className="collectionSchema-header-toggler" onClick={() => this.toggleIsOpen()}>{this.menuContent}</div>
+ </ Flyout > */}
+ {this.renderContent(this.col)}
+ </div>
+ );
+ }
private createTarget = (ele: HTMLDivElement) => {
this._previewCont = ele;
@@ -923,90 +451,41 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
</div>;
}
-
- // this is added too
- renderSchemaTable = (Document: any, dataDoc: any, childDocs: any) => {
- return <div className="collectionSchemaView-table" onPointerDown={this.onPointDown} onWheel={e => this.props.active(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} onContextMenu={this.onContextMenu} >
- {this.reactTable}
- <div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
- {!this._showDoc ? (null) :
- <div className="collectionSchemaView-documentPreview" //onClick={() => { this.onOpenClick(); }}
- style={{
- position: "absolute", width: 150, height: 150,
- background: "dimGray", display: "block", top: 0, left: 0,
- transform: `translate(${this._showDocPos[0]}px, ${this._showDocPos[1] - 180}px)`
- }}
- ref="overlay"><ContentFittingDocumentView
- Document={Document}
- DataDoc={dataDoc}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- fitToBox={true}
- FreezeDimensions={true}
- focus={emptyFunction}
- LibraryPath={emptyPath}
- renderDepth={this.props.renderDepth}
- rootSelected={() => false}
- PanelWidth={() => 150}
- PanelHeight={() => 150}
- ScreenToLocalTransform={this.getPreviewTransform}
- docFilters={returnEmptyFilter}
- ContainingCollectionDoc={this.props.CollectionView?.props.Document}
- ContainingCollectionView={this.props.CollectionView}
- moveDocument={this.props.moveDocument}
- parentActive={this.props.active}
- whenActiveChanged={emptyFunction}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- bringToFront={returnFalse}
- ContentScaling={returnOne}>
- </ContentFittingDocumentView>
- </div>}
- </div>;
- }
-
-
- // changed to render schema table
@computed
get schemaTable() {
const preview = "";
- return <div className="collectionSchemaView-table" onPointerDown={this.onPointDown} onWheel={e => this.props.active(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} onContextMenu={this.onContextMenu} >
- {this.reactTable}
- <div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
- {!this._showDoc ? (null) :
- <div className="collectionSchemaView-documentPreview" //onClick={() => { this.onOpenClick(); }}
- style={{
- position: "absolute", width: 150, height: 150,
- background: "dimGray", display: "block", top: 0, left: 0,
- transform: `translate(${this._showDocPos[0]}px, ${this._showDocPos[1] - 180}px)`
- }}
- ref="overlay"><ContentFittingDocumentView
- Document={this._showDoc}
- DataDoc={this._showDataDoc}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- fitToBox={true}
- FreezeDimensions={true}
- focus={emptyFunction}
- LibraryPath={emptyPath}
- renderDepth={this.props.renderDepth}
- rootSelected={() => false}
- PanelWidth={() => 150}
- PanelHeight={() => 150}
- ScreenToLocalTransform={this.getPreviewTransform}
- docFilters={returnEmptyFilter}
- ContainingCollectionDoc={this.props.CollectionView?.props.Document}
- ContainingCollectionView={this.props.CollectionView}
- moveDocument={this.props.moveDocument}
- parentActive={this.props.active}
- whenActiveChanged={emptyFunction}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- bringToFront={returnFalse}
- ContentScaling={returnOne}>
- </ContentFittingDocumentView>
- </div>}
- </div>;
+ return <SchemaTable
+ Document={this.props.Document}
+ PanelHeight={this.props.PanelHeight}
+ PanelWidth={this.props.PanelWidth}
+ childDocs={this.childDocs}
+ CollectionView={this.props.CollectionView}
+ ContainingCollectionView={this.props.ContainingCollectionView}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc}
+ fieldKey={this.props.fieldKey}
+ renderDepth={this.props.renderDepth}
+ moveDocument={this.props.moveDocument}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ active={this.props.active}
+ onDrop={this.onExternalDrop}
+ addDocTab={this.props.addDocTab}
+ pinToPres={this.props.pinToPres}
+ isSelected={this.props.isSelected}
+ isFocused={this.isFocused}
+ setFocused={this.setFocused}
+ setPreviewDoc={this.setPreviewDoc}
+ deleteDocument={this.props.removeDocument}
+ addDocument={this.props.addDocument}
+ dataDoc={this.props.DataDoc}
+ columns={this.columns}
+ documentKeys={this.documentKeys}
+ headerIsEditing={this._headerIsEditing}
+ openHeader={this.openHeader}
+ onPointerDown={this.onTablePointerDown}
+ onResizedChange={this.onResizedChange}
+ setColumns={this.setColumns}
+ reorderColumns={this.reorderColumns}
+ />;
}
@computed
@@ -1018,6 +497,44 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
</div>;
}
+ @action
+ onTablePointerDown = (e: React.PointerEvent): void => {
+ this.setFocused(this.props.Document);
+ if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected(true)) {
+ e.stopPropagation();
+ }
+ this.pointerY = e.screenY;
+ this.pointerX = e.screenX;
+ this.headerOpen = false;
+ }
+
+ onResizedChange = (newResized: Resize[], event: any) => {
+ const columns = this.columns;
+ newResized.forEach(resized => {
+ const index = columns.findIndex(c => c.heading === resized.id);
+ const column = columns[index];
+ column.setWidth(resized.value);
+ columns[index] = column;
+ });
+ this.columns = columns;
+ }
+
+ @action
+ setColumns = (columns: SchemaHeaderField[]) => this.columns = columns
+
+ @undoBatch
+ reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
+ const columns = [...columnsValues];
+ const oldIndex = columns.indexOf(toMove);
+ const relIndex = columns.indexOf(relativeTo);
+ const newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex;
+
+ if (oldIndex === newIndex) return;
+
+ columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]);
+ this.columns = columns;
+ }
+
render() {
return <div className="collectionSchemaView-container"
style={{
@@ -1036,14 +553,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
-
-
-
-
-
-
-
-
export interface SchemaTableProps {
Document: Doc; // child doc
dataDoc?: Doc;
@@ -1067,17 +576,20 @@ export interface SchemaTableProps {
isFocused: (document: Doc) => boolean;
setFocused: (document: Doc) => void;
setPreviewDoc: (document: Doc) => void;
+ columns: SchemaHeaderField[];
+ documentKeys: any[];
+ headerIsEditing: boolean;
+ openHeader: (column: any, menu: any) => void;
+ onPointerDown: (e: React.PointerEvent) => void;
+ onResizedChange: (newResized: Resize[], event: any) => void;
+ setColumns: (columns: SchemaHeaderField[]) => void;
+ reorderColumns: (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => void;
}
-
-
-
-
@observer
export class SchemaTable extends React.Component<SchemaTableProps> {
private DIVIDER_WIDTH = 4;
- @observable _headerIsEditing: boolean = false;
@observable _cellIsEditing: boolean = false;
@observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 };
@observable _openCollections: Array<string> = [];
@@ -1090,13 +602,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
@computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; }
@computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); }
- @computed get columns() {
- return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []);
- }
- set columns(columns: SchemaHeaderField[]) {
- this.props.Document.schemaColumns = new List<SchemaHeaderField>(columns);
- }
-
@computed get childDocs() {
if (this.props.childDocs) return this.props.childDocs;
@@ -1116,13 +621,13 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
@computed get resized(): { id: string, value: number }[] {
- return this.columns.reduce((resized, shf) => {
+ return this.props.columns.reduce((resized, shf) => {
(shf.width > -1) && resized.push({ id: shf.heading, value: shf.width });
return resized;
}, [] as { id: string, value: number }[]);
}
@computed get sorted(): SortingRule[] {
- return this.columns.reduce((sorted, shf) => {
+ return this.props.columns.reduce((sorted, shf) => {
shf.desc && sorted.push({ id: shf.heading, desc: shf.desc });
return sorted;
}, [] as SortingRule[]);
@@ -1131,12 +636,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
@computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
@computed get tableColumns(): Column<Doc>[] {
- const possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
+ const possibleKeys = this.props.documentKeys.filter(key => this.props.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
const columns: Column<Doc>[] = [];
const tableIsFocused = this.props.isFocused(this.props.Document);
const focusedRow = this._focusedCell.row;
const focusedCol = this._focusedCell.col;
- const isEditable = !this._headerIsEditing;
+ const isEditable = !this.props.headerIsEditing;
if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) {
columns.push(
@@ -1156,7 +661,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
);
}
- const cols = this.columns.map(col => {
+ const cols = this.props.columns.map(col => {
const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
this.getColumnType(col) === ColumnType.Boolean ? "check-square" : this.getColumnType(col) === ColumnType.Doc ? "file" :
@@ -1164,51 +669,21 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
- const header = <div><FontAwesomeIcon icon={icon} size="sm" />{col.heading}</div>;
-
- // <div className="collectionSchemaView-header" style={{ background: col.color }}>
- // <CollectionSchemaColumnMenu
- // columnField={col}
- // // keyValue={this.props.keyValue.heading}
- // possibleKeys={possibleKeys}
- // existingKeys={this.columns.map(c => c.heading)}
- // // keyType={this.getColumnType(col)}
- // typeConst={columnTypes.get(col.heading) !== undefined}
- // menuButtonContent={<div><FontAwesomeIcon icon={icon} size="sm" />{col.heading}</div>}
- // addNew={false}
- // onSelect={this.changeColumns}
- // setIsEditing={this.setHeaderIsEditing}
- // deleteColumn={this.deleteColumn}
- // onlyShowOptions={false}
- // setColumnType={this.setColumnType}
- // setColumnSort={this.setColumnSort}
- // setColumnColor={this.setColumnColor}
- // />
- // </div>;
-
-
- // <CollectionSchemaHeader
- // keyValue={col}
- // possibleKeys={possibleKeys}
- // existingKeys={this.columns.map(c => c.heading)}
- // keyType={this.getColumnType(col)}
- // typeConst={columnTypes.get(col.heading) !== undefined}
- // onSelect={this.changeColumns}
- // setIsEditing={this.setHeaderIsEditing}
- // deleteColumn={this.deleteColumn}
- // setColumnType={this.setColumnType}
- // setColumnSort={this.setColumnSort}
- // setColumnColor={this.setColumnColor}
- // />;
-
+ const menuContent = <div><FontAwesomeIcon icon={icon} size="sm" />{col.heading}</div>;
+ const header =
+ <div className="collectionSchemaView-header"
+ onClick={e => { this.props.openHeader(col, menuContent); }}
+ style={{ background: col.color }}>
+ {menuContent}
+ </div>;
return {
- Header: <MovableColumn columnRenderer={header} columnValue={col} allColumns={this.columns} reorderColumns={this.reorderColumns} ScreenToLocalTransform={this.props.ScreenToLocalTransform} />,
+ Header: <MovableColumn columnRenderer={header} columnValue={col} allColumns={this.props.columns} reorderColumns={this.props.reorderColumns} ScreenToLocalTransform={this.props.ScreenToLocalTransform} />,
accessor: (doc: Doc) => doc ? doc[col.heading] : 0,
id: col.heading,
Cell: (rowProps: CellInfo) => {
const rowIndex = rowProps.index;
- const columnIndex = this.columns.map(c => c.heading).indexOf(rowProps.column.id!);
+ const columnIndex = this.props.columns.map(c => c.heading).indexOf(rowProps.column.id!);
const isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused;
const props: CellProps = {
@@ -1286,7 +761,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
addDoc: this.tableAddDoc,
removeDoc: this.props.deleteDocument,
rowInfo,
- rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
+ rowFocused: !this.props.headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
textWrapRow: this.toggleTextWrapRow,
rowWrapped: this.textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1,
dropAction: StrCast(this.props.Document.childDropAction),
@@ -1304,7 +779,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
// TODO: editing border doesn't work :(
return {
style: {
- border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb"
+ border: !this.props.headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb"
}
};
}
@@ -1317,18 +792,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
@action onExpandCollection = (collection: Doc) => this._openCollections.push(collection[Id]);
@action setCellIsEditing = (isEditing: boolean) => this._cellIsEditing = isEditing;
- @action setHeaderIsEditing = (isEditing: boolean) => this._headerIsEditing = isEditing;
-
- onPointerDown = (e: React.PointerEvent): void => {
- this.props.setFocused(this.props.Document);
- if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected(true)) {
- e.stopPropagation();
- }
- }
@action
onKeyDown = (e: KeyboardEvent): void => {
- if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected(true)) {
+ if (!this._cellIsEditing && !this.props.headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected(true)) {
const direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
this._focusedCell = this.changeFocusedCellByDirection(direction, this._focusedCell.row, this._focusedCell.col);
@@ -1339,8 +806,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
changeFocusedCellByDirection = (direction: string, curRow: number, curCol: number) => {
switch (direction) {
- case "tab": return { row: (curRow + 1 === this.childDocs.length ? 0 : curRow + 1), col: curCol + 1 === this.columns.length ? 0 : curCol + 1 };
- case "right": return { row: curRow, col: curCol + 1 === this.columns.length ? curCol : curCol + 1 };
+ case "tab": return { row: (curRow + 1 === this.childDocs.length ? 0 : curRow + 1), col: curCol + 1 === this.props.columns.length ? 0 : curCol + 1 };
+ case "right": return { row: curRow, col: curCol + 1 === this.props.columns.length ? curCol : curCol + 1 };
case "left": return { row: curRow, col: curCol === 0 ? curCol : curCol - 1 };
case "up": return { row: curRow === 0 ? curRow : curRow - 1, col: curCol };
case "down": return { row: curRow + 1 === this.childDocs.length ? curRow : curRow + 1, col: curCol };
@@ -1365,49 +832,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
@action
createColumn = () => {
let index = 0;
- let found = this.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
+ let found = this.props.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
while (found) {
index++;
- found = this.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
- }
- this.columns.push(new SchemaHeaderField(`New field ${index ? "(" + index + ")" : ""}`, "#f1efeb"));
- }
-
- @undoBatch
- @action
- deleteColumn = (key: string) => {
- const columns = this.columns;
- if (columns === undefined) {
- this.columns = new List<SchemaHeaderField>([]);
- } else {
- const index = columns.map(c => c.heading).indexOf(key);
- if (index > -1) {
- columns.splice(index, 1);
- this.columns = columns;
- }
- }
- }
-
- @undoBatch
- @action
- changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
- const columns = this.columns;
- if (columns === undefined) {
- this.columns = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
- } else {
- if (addNew) {
- columns.push(new SchemaHeaderField(newKey, "f1efeb"));
- this.columns = columns;
- } else {
- const index = columns.map(c => c.heading).indexOf(oldKey);
- if (index > -1) {
- const column = columns[index];
- column.setHeading(newKey);
- columns[index] = column;
- this.columns = columns;
- }
- }
+ found = this.props.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
}
+ this.props.columns.push(new SchemaHeaderField(`New field ${index ? "(" + index + ")" : ""}`, "#f1efeb"));
}
getColumnType = (column: SchemaHeaderField): ColumnType => {
@@ -1429,72 +859,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
@undoBatch
- setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
- if (columnTypes.get(columnField.heading)) return;
-
- const columns = this.columns;
- const index = columns.indexOf(columnField);
- if (index > -1) {
- columnField.setType(NumCast(type));
- columns[index] = columnField;
- this.columns = columns;
- }
- }
-
- @undoBatch
- setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
- const columns = this.columns;
- const index = columns.indexOf(columnField);
- if (index > -1) {
- columnField.setColor(color);
- columns[index] = columnField;
- this.columns = columns; // need to set the columns to trigger rerender
- }
- }
-
- @action
- setColumns = (columns: SchemaHeaderField[]) => this.columns = columns
-
- @undoBatch
- reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
- const columns = [...columnsValues];
- const oldIndex = columns.indexOf(toMove);
- const relIndex = columns.indexOf(relativeTo);
- const newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex;
-
- if (oldIndex === newIndex) return;
-
- columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]);
- this.columns = columns;
- }
-
- @undoBatch
- @action
- setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
- const columns = this.columns;
- const index = columns.findIndex(c => c.heading === columnField.heading);
- const column = columns[index];
- column.setDesc(descending);
- columns[index] = column;
- this.columns = columns;
- }
-
- get documentKeys() {
- const docs = this.childDocs;
- const keys: { [key: string]: boolean } = {};
- // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields.
- // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be
- // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked.
- // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu
- // is displayed (unlikely) it won't show up until something else changes.
- //TODO Types
- untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false))));
-
- this.columns.forEach(key => keys[key.heading] = true);
- return Array.from(Object.keys(keys));
- }
-
- @undoBatch
@action
toggleTextwrap = async () => {
const textwrappedRows = Cast(this.props.Document.textwrappedSchemaRows, listSpec("string"), []);
@@ -1541,24 +905,13 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
sorted={this.sorted}
expanded={expanded}
resized={this.resized}
- onResizedChange={this.onResizedChange}
+ onResizedChange={this.props.onResizedChange}
SubComponent={!hasCollectionChild ? undefined : row => (row.original.type !== "collection") ? (null) :
<div className="reactTable-sub"><SchemaTable {...this.props} Document={row.original} dataDoc={undefined} childDocs={undefined} /></div>}
/>;
}
- onResizedChange = (newResized: Resize[], event: any) => {
- const columns = this.columns;
- newResized.forEach(resized => {
- const index = columns.findIndex(c => c.heading === resized.id);
- const column = columns[index];
- column.setWidth(resized.value);
- columns[index] = column;
- });
- this.columns = columns;
- }
-
onContextMenu = (e: React.MouseEvent): void => {
if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
// ContextMenu.Instance.addItem({ description: "Make DB", event: this.makeDB, icon: "table" });
@@ -1571,13 +924,13 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
row = row % docs.length;
while (row < 0) row += docs.length;
- const columns = this.columns;
+ const columns = this.props.columns;
const doc = docs[row];
if (col === undefined) {
return doc;
}
if (col >= 0 && col < columns.length) {
- const column = this.columns[col].heading;
+ const column = this.props.columns[col].heading;
return doc[column];
}
return undefined;
@@ -1658,7 +1011,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
render() {
const preview = "";
- return <div className="collectionSchemaView-table" onPointerDown={this.onPointerDown} onWheel={e => this.props.active(true) && e.stopPropagation()} onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
+ return <div className="collectionSchemaView-table" onPointerDown={this.props.onPointerDown} onWheel={e => this.props.active(true) && e.stopPropagation()} onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
{this.reactTable}
<div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
{!this._showDoc ? (null) :