diff options
3 files changed, 111 insertions, 14 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 5ead99c02..4f644717b 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -31,7 +31,7 @@ } .schema-row { - justify-content: space-evenly; + justify-content: flex-end; .row-menu { display: flex; @@ -39,13 +39,16 @@ justify-content: center; .row-button { - width: 20px; - height: 20px; + width: 25px; + height: 25px; border-radius: 100%; background-color: $dark-gray; color: white; - padding: 5px; + margin: 3px; cursor: pointer; + display: flex; + align-items: center; + justify-content: center; } } diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index dc0cd8eac..02bc55e7a 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -1,15 +1,26 @@ import React = require('react'); import { action, computed, observable, ObservableSet } from 'mobx'; import { observer } from 'mobx-react'; -import { Doc } from '../../../../fields/Doc'; +import { Doc, DocListCast } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; import { listSpec } from '../../../../fields/Schema'; -import { Cast } from '../../../../fields/Types'; +import { Cast, StrCast } from '../../../../fields/Types'; import { DragManager } from '../../../util/DragManager'; import { CollectionSubView } from '../CollectionSubView'; import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; +import { SelectionManager } from '../../../util/SelectionManager'; +import { undoBatch } from '../../../util/UndoManager'; +import { EditableView } from '../../EditableView'; +import { returnEmptyString } from '../../../../Utils'; +import { Docs, DocUtils } from '../../../documents/Documents'; +import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; +import { ContextMenu } from '../../ContextMenu'; +import { ContextMenuProps } from '../../ContextMenuItem'; +import { Id } from '../../../../fields/FieldSymbols'; +import { RichTextField } from '../../../../fields/RichTextField'; +import { ImageField } from '../../../../fields/URLField'; export enum ColumnType { Number, @@ -33,18 +44,19 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _isDragging: boolean = false; @computed get columnKeys() { - return Cast(this.props.Document.columnKeys, listSpec('string'), defaultColumnKeys); + return Cast(this.layoutDoc.columnKeys, listSpec('string'), defaultColumnKeys); } @computed get columnWidths() { return Cast( - this.props.Document.columnWidths, + this.layoutDoc.columnWidths, listSpec('number'), this.columnKeys.map(() => (this.props.PanelWidth() - this._rowMenuWidth) / this.columnKeys.length) ); } @action + @undoBatch changeColumnKey = (index: number, newKey: string) => { let currKeys = this.columnKeys; currKeys[index] = newKey; @@ -76,6 +88,13 @@ export class CollectionSchemaView extends CollectionSubView() { this._selectedDocs.add(doc); this._lastSelectedRow = index; } + + if (this._lastSelectedRow && this._selectedDocs.size > 0) { + SelectionManager.SelectSchemaViewDoc(this.childDocs[this._lastSelectedRow]); + } + else { + SelectionManager.SelectSchemaViewDoc(undefined); + } }; @action @@ -106,6 +125,8 @@ export class CollectionSchemaView extends CollectionSubView() { if (!this._selectedDocs.has(doc)) { this._selectedDocs.clear(); this._selectedDocs.add(doc); + this._lastSelectedRow = this.childDocs.indexOf(doc); + SelectionManager.SelectSchemaViewDoc(doc); } this._isDragging = true; this._selectedDocSortedArray = this.sortedSelectedDocs(); @@ -130,6 +151,83 @@ export class CollectionSchemaView extends CollectionSubView() { return true; }; + @action + addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => { + if (!value && !forceEmptyNote) return false; + const newDoc = Docs.Create.TextDocument(value, {title: value}); + FormattedTextBox.SelectOnLoad = newDoc[Id]; + FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' '; + return this.props.addDocument?.(newDoc) || false; + }; + + menuCallback = (x: number, y: number) => { + ContextMenu.Instance.clearItems(); + const layoutItems: ContextMenuProps[] = []; + const docItems: ContextMenuProps[] = []; + const dataDoc = this.props.DataDoc || this.props.Document; + + DocUtils.addDocumentCreatorMenuItems( + doc => { + FormattedTextBox.SelectOnLoad = StrCast(doc[Id]); + return this.addDocument(doc); + }, + this.addDocument, + x, + y, + true + ); + + Array.from(Object.keys(Doc.GetProto(dataDoc))) + .filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof dataDoc[fieldKey] === 'string') + .map(fieldKey => + docItems.push({ + description: ':' + fieldKey, + event: () => { + const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document)); + if (created) { + if (this.props.Document.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this.props.Document); + } + return this.props.addDocument?.(created); + } + }, + icon: 'compress-arrows-alt', + }) + ); + Array.from(Object.keys(Doc.GetProto(dataDoc))) + .filter(fieldKey => DocListCast(dataDoc[fieldKey]).length) + .map(fieldKey => + docItems.push({ + description: ':' + fieldKey, + event: () => { + const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey }); + if (created) { + const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document; + if (container.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, container); + return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created); + } + return this.props.addDocument?.(created) || false; + } + }, + icon: 'compress-arrows-alt', + }) + ); + !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' }); + !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' }); + ContextMenu.Instance.setDefaultItem('::', (name: string): void => { + Doc.GetProto(this.props.Document)[name] = ''; + const created = Docs.Create.TextDocument('', { title: name, _width: 250, _autoHeight: true }); + if (created) { + if (this.props.Document.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this.props.Document); + } + this.props.addDocument?.(created); + } + }); + ContextMenu.Instance.displayMenu(x, y, undefined, true); + }; + render() { return ( <div @@ -165,6 +263,7 @@ export class CollectionSchemaView extends CollectionSubView() { ))} </div> </div> + <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} /> </div> ); } diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 8b658d834..ea2ebed7a 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -90,14 +90,9 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { <div className="row-button" onPointerDown={(e) => {e.stopPropagation(); this.props.addDocTab(this.props.Document, 'add:right')}}> <FontAwesomeIcon icon="external-link-alt" /> </div> - <div className="row-button"> - {this.props.rowIndex} - </div> </div> <div className="row-cells"> - {this.props.columnKeys.map((key, index) => ( - <SchemaTableCell Document={this.props.Document} key={key} fieldKey={key} columnWidth={this.props.columnWidths[index]} /> - ))} + {this.props.columnKeys.map((key, index) => (<SchemaTableCell Document={this.props.Document} fieldKey={key} columnWidth={this.props.columnWidths[index]} />))} </div> </div> ); |