diff options
| author | bobzel <zzzman@gmail.com> | 2023-04-05 22:44:03 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2023-04-05 22:44:03 -0400 |
| commit | 9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch) | |
| tree | bc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/client/views/collections/CollectionNoteTakingViewColumn.tsx | |
| parent | 9dae453967183b294bf4f7444b948023a1d52d39 (diff) | |
| parent | 8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff) | |
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/client/views/collections/CollectionNoteTakingViewColumn.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionNoteTakingViewColumn.tsx | 98 |
1 files changed, 39 insertions, 59 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index 624beca96..28bdd0cb9 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -3,13 +3,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; -import { Id } from '../../../fields/FieldSymbols'; +import { Copy, Id } from '../../../fields/FieldSymbols'; import { RichTextField } from '../../../fields/RichTextField'; +import { listSpec } from '../../../fields/Schema'; import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; -import { ScriptField } from '../../../fields/ScriptField'; +import { Cast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, returnEmptyString, setupMoveUpEvents } from '../../../Utils'; +import { returnEmptyString } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; @@ -21,13 +22,7 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from '../EditableView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import './CollectionNoteTakingView.scss'; -import { listSpec } from '../../../fields/Schema'; -import { Cast } from '../../../fields/Types'; -const higflyout = require('@hig/flyout'); -export const { anchorPoints } = higflyout; -export const Flyout = higflyout.default; -// So this is how we are storing a column interface CSVFieldColumnProps { Document: Doc; DataDoc: Opt<Doc>; @@ -38,54 +33,47 @@ interface CSVFieldColumnProps { columnHeaders: SchemaHeaderField[] | undefined; headingObject: SchemaHeaderField | undefined; yMargin: number; - // columnWidth: number; numGroupColumns: number; gridGap: number; type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined; headings: () => object[]; + select: (ctrlPressed: boolean) => void; renderChildren: (docs: Doc[]) => JSX.Element[]; addDocument: (doc: Doc | Doc[]) => boolean; createDropTarget: (ele: HTMLDivElement) => void; screenToLocalTransform: () => Transform; observeHeight: (myref: any) => void; unobserveHeight: (myref: any) => void; - //setDraggedCol:(clonedDiv:any, header:SchemaHeaderField, xycoors: ) editableViewProps: () => any; - resizeColumns: (n: number) => void; - columnStartXCoords: number[]; - PanelWidth: number; + resizeColumns: (headers: SchemaHeaderField[]) => boolean; maxColWidth: number; - // docsByColumnHeader: Map<string, Doc[]> - // setDocsForColHeader: (key: string, docs: Doc[]) => void + dividerWidth: number; + availableWidth: number; } +/** + * CollectionNoteTakingViewColumn represents an individual column rendered in CollectionNoteTakingView. The + * majority of functions here are for rendering styles. + */ @observer export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColumnProps> { @observable private _background = 'inherit'; + // columnWidth returns the width of a column in absolute pixels @computed get columnWidth() { - // base cases - if (!this.props.columnHeaders || !this.props.headingObject || this.props.columnHeaders.length == 1) { - return this.props.maxColWidth; - } + if (!this.props.columnHeaders || !this.props.headingObject || this.props.columnHeaders.length === 1) return '100%'; const i = this.props.columnHeaders.indexOf(this.props.headingObject); - if (i < 0 || i > this.props.columnStartXCoords.length - 1) { - return this.props.maxColWidth; - } - const endColValue = i == this.props.numGroupColumns - 1 ? this.props.PanelWidth : this.props.columnStartXCoords[i + 1]; - // TODO make the math work here. 35 is half of 70, which is the current width of the divider - return endColValue - this.props.columnStartXCoords[i] - 30; + return this.props.columnHeaders[i].width * 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'; _ele: HTMLElement | null = null; - // This is likely similar to what we will be doing. Why do we need to make these refs? - // is that the only way to have drop targets? createColumnDropRef = (ele: HTMLDivElement | null) => { this.dropDisposer?.(); if (ele) { @@ -134,6 +122,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu @action pointerLeave = () => (this._background = 'inherit'); textCallback = (char: string) => this.addNewTextDoc('-typed text-', false, true); + // addNewTextDoc is called when a user starts typing in a column to create a new node @action addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => { if (!value && !forceEmptyNote) return false; @@ -146,14 +135,17 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu 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 columnHeaders = Cast(this.props.Document.columnHeaders, listSpec(SchemaHeaderField), null); - if (columnHeaders && this.props.headingObject) { - const index = columnHeaders.indexOf(this.props.headingObject); - this.props.docList.forEach(d => (d[this.props.pivotField] = 'unset')); - columnHeaders.splice(index, 1); + const columnHeaders = Array.from(Cast(this.props.Document.columnHeaders, listSpec(SchemaHeaderField), null)); + if (this.props.headingObject) { + this.props.docList.forEach(d => (d[this.props.pivotField] = undefined)); + columnHeaders.splice(columnHeaders.indexOf(this.props.headingObject), 1); + this.props.resizeColumns(columnHeaders); } }; @@ -243,62 +235,51 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu ref={this._headerRef} style={{ marginTop: 2 * this.props.yMargin, - // width: (this.props.columnWidth) / - // ((uniqueHeadings.length) || 1) - width: this.columnWidth - 20, + 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} 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.columnHeaders?.length ?? 0) > 1 && ( + <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}> + <FontAwesomeIcon icon="trash" size="lg" /> + </button> + )} </div> ) : null; - // const templatecols = `${this.props.columnWidth / this.props.numGroupColumns}px `; - const templatecols = `${this.columnWidth}px `; + const templatecols = this.columnWidth; const type = this.props.Document.type; return ( <> {headingView} - { - <div style={{ height: '100%' }}> + <div className="collectionNoteTakingView-columnStackContainer"> + <div className="collectionNoteTakingView-columnStack"> <div key={`${heading}-stack`} className={`collectionNoteTakingView-Nodes`} style={{ padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`, - margin: 'auto', - width: 'max-content', //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`, - height: 'max-content', - position: 'relative', gridGap: this.props.gridGap, gridTemplateColumns: templatecols, - gridAutoRows: '0px', }}> {this.props.renderChildren(this.props.docList)} </div> - {!this.props.chromeHidden && type !== DocumentType.PRES ? ( - <div - className="collectionNoteTakingView-DocumentButtons" - // style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10 }}> - style={{ width: this.columnWidth - 20, marginBottom: 10 }}> + {!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.textCallback} 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> - {this.props.columnHeaders?.length && this.props.columnHeaders.length > 1 && ( - <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}> - <FontAwesomeIcon icon="trash" size="lg" /> - </button> - )} </div> ) : null} </div> - } + </div> </> ); } @@ -308,10 +289,9 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu const heading = this._heading; return ( <div - className={'collectionNoteTakingViewFieldColumn' + (SnappingManager.GetIsDragging() ? 'Dragging' : '')} + className="collectionNoteTakingViewFieldColumn" key={heading} style={{ - //TODO: change this so that it's based on the column width width: this.columnWidth, background: this._background, }} |
