diff options
Diffstat (limited to 'src/client/views/collections/CollectionNoteTakingViewColumn.tsx')
-rw-r--r-- | src/client/views/collections/CollectionNoteTakingViewColumn.tsx | 133 |
1 files changed, 66 insertions, 67 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index 52cc21903..38846c79d 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -1,18 +1,17 @@ -import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, trace } from 'mobx'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; +import { returnEmptyString } from '../../../Utils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; -import { Copy, Id } from '../../../fields/FieldSymbols'; +import { Id } from '../../../fields/FieldSymbols'; import { RichTextField } from '../../../fields/RichTextField'; import { listSpec } from '../../../fields/Schema'; import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { Cast, NumCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { returnEmptyString } from '../../../Utils'; -import { Docs, DocUtils } from '../../documents/Documents'; -import { DocumentType } from '../../documents/DocumentTypes'; +import { DocUtils, Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; @@ -20,12 +19,13 @@ import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from '../EditableView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import './CollectionNoteTakingView.scss'; interface CSVFieldColumnProps { Document: Doc; - DataDoc: Opt<Doc>; + TemplateDataDocument: Opt<Doc>; docList: Doc[]; heading: string; pivotField: string; @@ -58,43 +58,43 @@ interface CSVFieldColumnProps { * majority of functions here are for rendering styles. */ @observer -export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColumnProps> { +export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSVFieldColumnProps> { @observable private _background = 'inherit'; // columnWidth returns the width of a column in absolute pixels @computed get columnWidth() { - if (!this.props.colHeaderData || !this.props.headingObject || this.props.colHeaderData.length === 1) return `${(this.props.availableWidth / this.props.PanelWidth()) * 100}%`; - const i = this.props.colHeaderData.indexOf(this.props.headingObject); - return ((this.props.colHeaderData[i].width * this.props.availableWidth) / this.props.PanelWidth()) * 100 + '%'; + if (!this._props.colHeaderData || !this._props.headingObject || this._props.colHeaderData.length === 1) return `${(this._props.availableWidth / this._props.PanelWidth()) * 100}%`; + const i = this._props.colHeaderData.findIndex(hd => hd.heading === this._props.headingObject?.heading && hd.color === this._props.headingObject.color); + return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%'; } private dropDisposer?: DragManager.DragDropDisposer; private _headerRef: React.RefObject<HTMLDivElement> = React.createRef(); public static ColumnMargin = 10; - @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading; - @observable _color = this.props.headingObject ? this.props.headingObject.color : '#f1efeb'; + @observable _heading = this._props.headingObject ? this._props.headingObject.heading : this._props.heading; + @observable _color = this._props.headingObject ? this._props.headingObject.color : '#f1efeb'; _ele: HTMLElement | null = null; createColumnDropRef = (ele: HTMLDivElement | null) => { this.dropDisposer?.(); if (ele) { this._ele = ele; - this.props.observeHeight(ele); - this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this)); + this._props.observeHeight(ele); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document); } }; componentWillUnmount() { - this.props.unobserveHeight(this._ele); + this._props.unobserveHeight(this._ele); } @undoBatch - columnDrop = action((e: Event, de: DragManager.DropEvent) => { + columnDrop = (e: Event, de: DragManager.DropEvent) => { const drop = { docs: de.complete.docDragData?.droppedDocuments, val: this.getValue(this._heading) }; - drop.docs?.forEach(d => Doc.SetInPlace(d, this.props.pivotField, drop.val, false)); + drop.docs?.forEach(d => Doc.SetInPlace(d, this._props.pivotField, drop.val, false)); return true; - }); + }; getValue = (value: string): any => { const parsed = parseInt(value); @@ -108,20 +108,20 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu headingChanged = (value: string, shiftDown?: boolean) => { const castedValue = this.getValue(value); if (castedValue) { - if (this.props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) { + if (this._props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) { return false; } - this.props.docList.forEach(d => (d[this.props.pivotField] = castedValue)); - if (this.props.headingObject) { - this.props.headingObject.setHeading(castedValue.toString()); - this._heading = this.props.headingObject.heading; + this._props.docList.forEach(d => (d[this._props.pivotField] = castedValue)); + if (this._props.headingObject) { + this._props.headingObject.setHeading(castedValue.toString()); + this._heading = this._props.headingObject.heading; } return true; } return false; }; - @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4'); + @action pointerEntered = () => SnappingManager.IsDragging && (this._background = '#b4b4b4'); @action pointerLeave = () => (this._background = 'inherit'); @undoBatch addTextNote = (char: string) => this.addNewTextDoc('-typed text-', false, true); @@ -130,26 +130,25 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu @action addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => { if (!value && !forceEmptyNote) return false; - const key = this.props.pivotField; + const key = this._props.pivotField; const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true }); - const colValue = this.getValue(this.props.heading); + const colValue = this.getValue(this._props.heading); newDoc[key] = colValue; - FormattedTextBox.SelectOnLoad = newDoc[Id]; + FormattedTextBox.SetSelectOnLoad(newDoc); FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' '; - return this.props.addDocument?.(newDoc) || false; + return this._props.addDocument?.(newDoc) || false; }; // deleteColumn is called when a user deletes a column using the 'trash' icon in the button area. // If the user deletes the first column, the documents get moved to the second column. Otherwise, // all docs are added to the column directly to the left. @undoBatch - @action deleteColumn = () => { - const colHdrData = Array.from(Cast(this.props.Document[this.props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); - if (this.props.headingObject) { - this.props.docList.forEach(d => (d[this.props.pivotField] = undefined)); - colHdrData.splice(colHdrData.indexOf(this.props.headingObject), 1); - this.props.resizeColumns(colHdrData); + const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); + if (this._props.headingObject) { + this._props.docList.forEach(d => (d[this._props.pivotField] = undefined)); + colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1); + this._props.resizeColumns(colHdrData); } }; @@ -157,21 +156,21 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu ContextMenu.Instance.clearItems(); const layoutItems: ContextMenuProps[] = []; const docItems: ContextMenuProps[] = []; - const dataDoc = this.props.DataDoc || this.props.Document; - const pivotValue = this.getValue(this.props.heading); + const dataDoc = this._props.TemplateDataDocument || this._props.Document; + const pivotValue = this.getValue(this._props.heading); DocUtils.addDocumentCreatorMenuItems( doc => { - const key = this.props.pivotField; - doc[key] = this.getValue(this.props.heading); - FormattedTextBox.SelectOnLoad = doc[Id]; - return this.props.addDocument?.(doc); + const key = this._props.pivotField; + doc[key] = this.getValue(this._props.heading); + FormattedTextBox.SetSelectOnLoad(doc); + return this._props.addDocument?.(doc); }, - this.props.addDocument, + this._props.addDocument, x, y, true, - this.props.pivotField, + this._props.pivotField, pivotValue ); @@ -181,12 +180,12 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu docItems.push({ description: ':' + fieldKey, event: () => { - const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document)); + const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document)); if (created) { - if (this.props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this.props.Document); + if (this._props.Document.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Document); } - return this.props.addDocument?.(created); + return this._props.addDocument?.(created); } }, icon: 'compress-arrows-alt', @@ -200,12 +199,12 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu 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; + 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; + return this._props.addDocument?.(created) || false; } }, icon: 'compress-arrows-alt', @@ -214,13 +213,13 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' }); !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' }); ContextMenu.Instance.setDefaultItem('::', (name: string): void => { - Doc.GetProto(this.props.Document)[name] = ''; + Doc.GetProto(this._props.Document)[name] = ''; const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true }); if (created) { - if (this.props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this.props.Document); + if (this._props.Document.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Document); } - this.props.addDocument?.(created); + this._props.addDocument?.(created); } }); ContextMenu.Instance.displayMenu(x, y, undefined, true); @@ -228,26 +227,26 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu @computed get innards() { TraceMobx(); - const key = this.props.pivotField; + const key = this._props.pivotField; const heading = this._heading; - const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin; + const columnYMargin = this._props.headingObject ? 0 : this._props.yMargin; const evContents = heading ? heading : '25'; - const headingView = this.props.headingObject ? ( + const headingView = this._props.headingObject ? ( <div key={heading} className="collectionNoteTakingView-sectionHeader" ref={this._headerRef} style={{ - marginTop: 2 * this.props.yMargin, + marginTop: 2 * this._props.yMargin, width: 'calc(100% - 5px)', }}> <div className="collectionNoteTakingView-sectionHeader-subCont" title={evContents === `No Value` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''} style={{ background: evContents !== `No Value` ? this._color : 'inherit' }}> - <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this.props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} /> + <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} /> </div> - {(this.props.colHeaderData?.length ?? 0) > 1 && ( + {(this._props.colHeaderData?.length ?? 0) > 1 && ( <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}> <FontAwesomeIcon icon="trash" size="lg" /> </button> @@ -255,7 +254,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu </div> ) : null; const templatecols = this.columnWidth; - const type = this.props.Document.type; + const type = this._props.Document.type; return ( <> {headingView} @@ -265,20 +264,20 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu key={`${heading}-stack`} className={`collectionNoteTakingView-Nodes`} style={{ - padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`, - gridGap: this.props.gridGap, + padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`, + gridGap: this._props.gridGap, gridTemplateColumns: templatecols, }}> - {this.props.renderChildren(this.props.docList)} + {this._props.renderChildren(this._props.docList)} </div> - {!this.props.chromeHidden ? ( + {!this._props.chromeHidden ? ( <div className="collectionNoteTakingView-DocumentButtons" style={{ marginBottom: 10 }}> <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton"> <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} /> </div> - <div key={`${this.props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton"> - <EditableView {...this.props.editableViewProps()} /> + <div key={`${this._props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton"> + <EditableView {...this._props.editableViewProps()} /> </div> </div> ) : null} @@ -298,7 +297,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu style={{ width: this.columnWidth, background: this._background, - marginLeft: this.props.headings().findIndex((h: any) => h[0] === this.props.headingObject) === 0 ? NumCast(this.props.Document.xMargin) : 0, + marginLeft: this._props.headings().findIndex((h: any) => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0, }} ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} |