diff options
| author | bobzel <zzzman@gmail.com> | 2024-10-10 20:06:17 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-10-10 20:06:17 -0400 |
| commit | 962302d41ba5b086818f5db9ea5103c1e754b66f (patch) | |
| tree | fe7b36ce2ac3c8276e4175e4dd8d5e223e1373a7 /src/client/views/collections/collectionSchema/SchemaRowBox.tsx | |
| parent | 3a35e2687e3c7b0c864dd4f00b1002ff088b56d3 (diff) | |
| parent | 040a1c5fd3e80606793e65be3ae821104460511b (diff) | |
Merge branch 'master' into alyssa-starter
Diffstat (limited to 'src/client/views/collections/collectionSchema/SchemaRowBox.tsx')
| -rw-r--r-- | src/client/views/collections/collectionSchema/SchemaRowBox.tsx | 141 |
1 files changed, 91 insertions, 50 deletions
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index a7e0e916b..6ffb0865a 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -1,10 +1,8 @@ import { IconButton, Size } from 'browndash-components'; -import { computed, makeObservable } from 'mobx'; +import { computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; -import { CgClose, CgLock, CgLockUnlock } from 'react-icons/cg'; -import { FaExternalLinkAlt } from 'react-icons/fa'; import { returnFalse, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { Doc } from '../../../../fields/Doc'; @@ -12,12 +10,20 @@ import { BoolCast } from '../../../../fields/Types'; import { Transform } from '../../../util/Transform'; import { undoable } from '../../../util/UndoManager'; import { ViewBoxBaseComponent } from '../../DocComponent'; -import { Colors } from '../../global/globalEnums'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { OpenWhere } from '../../nodes/OpenWhere'; import { CollectionSchemaView } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; import { SchemaTableCell } from './SchemaTableCell'; +import { ContextMenu } from '../../ContextMenu'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; + +/** + * The SchemaRowBox renders a doc as a row of cells, with each cell representing + * one field value of the doc. It mostly handles communication from the SchemaView + * to each SchemaCell, passing down necessary functions are props. + */ interface SchemaRowBoxProps extends FieldViewProps { rowIndex: number; @@ -28,6 +34,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { return FieldView.LayoutString(SchemaRowBox, fieldKey).replace('fieldKey', `rowIndex={${rowIndex}} fieldKey`); } private _ref: HTMLDivElement | null = null; + @observable _childrenAddedToSchema: boolean = false; constructor(props: SchemaRowBoxProps) { super(props); @@ -44,29 +51,85 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { return this.schemaView.Document; } - @computed get rowIndex() { - return this.schemaView?.rowIndex(this.Document) ?? -1; - } - componentDidMount(): void { this._props.setContentViewBox?.(this); } + openContextMenu = (x: number, y: number) => { + ContextMenu.Instance.clearItems(); + ContextMenu.Instance.addItem({ + description: this.Document._lockedSchemaEditing ? 'Unlock field editing' : 'Lock field editing', + event: () => (this.Document._lockedSchemaEditing = !this.Document._lockedSchemaEditing), + icon: this.Document._lockedSchemaEditing ? 'lock-open' : 'lock', + }); + ContextMenu.Instance.addItem({ + description: 'Open preview', + event: () => this._props.addDocTab(this.Document, OpenWhere.addRight), + icon: 'magnifying-glass', + }); + ContextMenu.Instance.addItem({ + description: `Close doc`, + event: () => this.schemaView.removeDoc(this.Document), + icon: 'minus', + }); + // Defunct option to add child docs of collections to the main schema + // const childDocs = DocListCast(this.Document[Doc.LayoutFieldKey(this.Document)]) + // if (this.Document.type === 'collection' && childDocs.length) { + // ContextMenu.Instance.addItem({ + // description: this.Document._childrenSharedWithSchema ? 'Remove children from schema' : 'Add children to schema', + // event: () => { + // this.Document._childrenSharedWithSchema = !this.Document._childrenSharedWithSchema; + // }, + // icon: this.Document._childrenSharedWithSchema ? 'minus' : 'plus', + // }); + // } + ContextMenu.Instance.displayMenu(x, y, undefined, false); + }; + + @computed get menuBackgroundColor() { + if (this.Document._lockedSchemaEditing) { + return '#F5F5F5'; + } + return ''; + } + + @computed get menuInfos() { + const infos: Array<IconProp> = []; + if (this.Document._lockedSchemaEditing) infos.push('lock'); + if (this.Document._childrenSharedWithSchema) infos.push('star'); + return infos; + } + + isolatedSelection = (doc: Doc) => { + return this.schemaView?.selectionOverlap(doc); + }; setCursorIndex = (mouseY: number) => this.schemaView?.setRelCursorIndex(mouseY); selectedCol = () => this.schemaView._selectedCol; getFinfo = computedFn((fieldKey: string) => this.schemaView?.fieldInfos.get(fieldKey)); selectCell = (doc: Doc, col: number, shift: boolean, ctrl: boolean) => this.schemaView?.selectCell(doc, col, shift, ctrl); deselectCell = () => this.schemaView?.deselectAllCells(); selectedCells = () => this.schemaView?._selectedDocs; - setColumnValues = (field: string, value: string) => this.schemaView?.setColumnValues(field, value) ?? false; - setSelectedColumnValues = (field: string, value: string) => this.schemaView?.setSelectedColumnValues(field, value) ?? false; + setColumnValues = (field: string, value: string) => this.schemaView?.setCellValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); + computeRowIndex = () => this.schemaView?.rowIndex(this.Document); + highlightCells = (text: string) => this.schemaView?.highlightCells(text); + selectReference = (doc: Doc, col: number) => { + this.schemaView.selectReference(doc, col); + }; + eqHighlightFunc = (text: string) => { + const info = this.schemaView.findCellRefs(text); + const cells: HTMLDivElement[] = []; + info.forEach(inf => { + cells.push(this.schemaView.getCellElement(inf[0], inf[1])); + }); + return cells; + }; render() { return ( <div className="schema-row" onPointerDown={e => this.setCursorIndex(e.clientY)} - style={{ height: this._props.PanelHeight(), backgroundColor: this._props.isSelected() ? Colors.LIGHT_BLUE : undefined }} + style={{ height: this._props.PanelHeight() }} ref={(row: HTMLDivElement | null) => { row && this.schemaView?.addRowRef?.(this.Document, row); this._ref = row; @@ -76,45 +139,13 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { style={{ width: CollectionSchemaView._rowMenuWidth, pointerEvents: !this._props.isContentActive() ? 'none' : undefined, + backgroundColor: this.menuBackgroundColor, }}> <IconButton - tooltip="close" - icon={<CgClose size="16px" />} - size={Size.XSMALL} - onPointerDown={e => - setupMoveUpEvents( - this, - e, - returnFalse, - emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - this._props.removeDocument?.(this.Document); - }, 'Delete Row') - ) - } - /> - <IconButton - tooltip="whether document interactions are enabled" - icon={this.Document._lockedPosition ? <CgLockUnlock size="12px" /> : <CgLock size="12px" />} - size={Size.XSMALL} - onPointerDown={e => - setupMoveUpEvents( - this, - e, - returnFalse, - emptyFunction, - undoable(clickEv => { - clickEv.stopPropagation(); - Doc.toggleLockedPosition(this.Document); - }, 'toggle document lock') - ) - } - /> - <IconButton - tooltip="open preview" - icon={<FaExternalLinkAlt />} + tooltip="Open actions menu" + icon={<FontAwesomeIcon icon="caret-right" size="lg" />} size={Size.XSMALL} + color={'black'} onPointerDown={e => setupMoveUpEvents( this, @@ -123,16 +154,27 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { emptyFunction, undoable(clickEv => { clickEv.stopPropagation(); - this._props.addDocTab(this.Document, OpenWhere.addRight); - }, 'Open schema Doc preview') + this.openContextMenu(e.clientX, e.clientY); + }, 'open actions menu') ) } /> + <div className="row-menu-infos"> + {this.menuInfos.map(icn => ( + <FontAwesomeIcon key={icn.toString()} className="row-infos-icon" icon={icn} size="2xs" /> + ))} + </div> </div> <div className="row-cells"> {this.schemaView?.columnKeys?.map((key, index) => ( <SchemaTableCell + selectReference={this.selectReference} + refSelectModeInfo={this.schemaView._referenceSelectMode} + eqHighlightFunc={this.eqHighlightFunc} + highlightCells={this.highlightCells} + isolatedSelection={this.isolatedSelection} key={key} + rowSelected={this._props.isSelected} Document={this.Document} col={index} fieldKey={key} @@ -146,7 +188,6 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() { selectedCells={this.selectedCells} selectedCol={this.selectedCol} setColumnValues={this.setColumnValues} - setSelectedColumnValues={this.setSelectedColumnValues} oneLine={BoolCast(this.schemaDoc?._singleLine)} menuTarget={this.schemaView.MenuTarget} transform={() => { |
