diff options
| author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-09 12:17:03 -0400 |
|---|---|---|
| committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-09 12:17:03 -0400 |
| commit | b158b7ffb564db8dc60da9b80b01b10f1ed8b7cf (patch) | |
| tree | af35e320eb876c12c617fda2eb70ce19ef376b67 /src/client/views/collections/collectionSchema/SchemaTableCell.tsx | |
| parent | eecc7ee1d14719d510ec2975826022c565a35e5f (diff) | |
| parent | 3b90916af8ffcbeaf5b8a3336009b84e19c22fa9 (diff) | |
Merge branch 'master' into sophie-ai-images
Diffstat (limited to 'src/client/views/collections/collectionSchema/SchemaTableCell.tsx')
| -rw-r--r-- | src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 001ad5ab6..bf36b2668 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -1,8 +1,11 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Popup, Size, Type } from 'browndash-components'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import { extname } from 'path'; import * as React from 'react'; import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; import Select from 'react-select'; import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../Utils'; import { DateField } from '../../../../fields/DateField'; @@ -10,8 +13,11 @@ import { Doc, DocListCast, Field } from '../../../../fields/Doc'; import { RichTextField } from '../../../../fields/RichTextField'; import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; -import { FInfo } from '../../../documents/Documents'; +import { FInfo, FInfoFieldType } from '../../../documents/Documents'; import { DocFocusOrOpen } from '../../../util/DocumentManager'; +import { dropActionType } from '../../../util/DragManager'; +import { SettingsManager } from '../../../util/SettingsManager'; +import { SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; import { undoBatch, undoable } from '../../../util/UndoManager'; import { EditableView } from '../../EditableView'; @@ -24,11 +30,6 @@ import { KeyValueBox } from '../../nodes/KeyValueBox'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { ColumnType, FInfotoColType } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; -import 'react-datepicker/dist/react-datepicker.css'; -import { Popup, Size, Type } from 'browndash-components'; -import { IconLookup, faCaretDown } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { SettingsManager } from '../../../util/SettingsManager'; export interface SchemaTableCellProps { Document: Doc; @@ -50,6 +51,8 @@ export interface SchemaTableCellProps { options?: string[]; menuTarget: HTMLDivElement | null; transform: () => Transform; + autoFocus?: boolean; // whether to set focus on creation, othwerise wait for a click + rootSelected?: () => boolean; } @observer @@ -86,18 +89,20 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro isSelected: returnFalse, setHeight: returnFalse, select: emptyFunction, - dragAction: 'move', + dragAction: dropActionType.move, renderDepth: 1, + noSidebar: true, isContentActive: returnFalse, whenChildContentsActiveChanged: emptyFunction, ScreenToLocalTransform: Transform.Identity, focus: emptyFunction, addDocTab: SchemaTableCell.addFieldDoc, pinToPres: returnZero, - Document, + Document: DocCast(Document.rootDocument, Document), fieldKey: fieldKey, PanelWidth: columnWidth, PanelHeight: props.rowHeight, + rootSelected: props.rootSelected, }; const readOnly = getFinfo(fieldKey)?.readOnly ?? false; const cursor = !readOnly ? 'text' : 'default'; @@ -123,17 +128,20 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro pointerEvents, }}> <EditableView + ref={r => this.selected && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} contents={undefined} fieldContents={fieldProps} editing={this.selected ? undefined : false} - GetValue={() => Field.toKeyValueString(this._props.Document, this._props.fieldKey)} + GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); + this._props.finishEdit?.(); + return true; } - const ret = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value); + const ret = KeyValueBox.SetField(fieldProps.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(fieldProps.Document) ? true : undefined); this._props.finishEdit?.(); return ret; }, 'edit schema cell')} @@ -149,7 +157,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro if (cellValue instanceof DateField) return ColumnType.Date; if (cellValue instanceof RichTextField) return ColumnType.RTF; if (typeof cellValue === 'number') return ColumnType.Any; - if (typeof cellValue === 'string' && columnTypeStr !== 'enumeration') return ColumnType.Any; + if (typeof cellValue === 'string' && columnTypeStr !== FInfoFieldType.enumeration) return ColumnType.Any; if (typeof cellValue === 'boolean') return ColumnType.Boolean; if (columnTypeStr && columnTypeStr in FInfotoColType) { @@ -205,7 +213,7 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro get url() { const field = Cast(this._props.Document[this._props.fieldKey], ImageField, null); // retrieve the primary image URL that is being rendered from the data doc - const alts = DocListCast(this._props.Document[this._props.fieldKey + '-alternates']); // retrieve alternate documents that may be rendered as alternate images + const alts = DocListCast(this._props.Document[this._props.fieldKey + '_alternates']); // retrieve alternate documents that may be rendered as alternate images const altpaths = alts .map(doc => Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url) .filter(url => url) @@ -311,13 +319,15 @@ export class SchemaRTFCell extends ObservableReactComponent<SchemaTableCellProps const selected: [Doc, number] | undefined = this._props.selectedCell(); return this._props.isRowActive() && selected?.[0] === this._props.Document && selected[1] === this._props.col; } + + // if the text box blurs and none of its contents are focused(), then the edit finishes selectedFunc = () => this.selected; render() { const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props); fieldProps.isContentActive = this.selectedFunc; return ( - <div className="schemaRTFCell" style={{ display: 'flex', fontStyle: this.selected ? undefined : 'italic', width: '100%', height: '100%', position: 'relative', color, textDecoration, cursor, pointerEvents }}> - {this.selected ? <FormattedTextBox {...fieldProps} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))} + <div className="schemaRTFCell" style={{ fontStyle: this.selected ? undefined : 'italic', color, textDecoration, cursor, pointerEvents }}> + {this.selected ? <FormattedTextBox {...fieldProps} autoFocus={true} onBlur={() => this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))} </div> ); } @@ -344,8 +354,7 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp onChange={undoBatch((value: React.ChangeEvent<HTMLInputElement> | undefined) => { if ((value?.nativeEvent as any).shiftKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString()); - } - KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString()); + } else KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString()); })} /> <EditableView @@ -356,8 +365,10 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); + this._props.finishEdit?.(); + return true; } - const set = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value); + const set = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined); this._props.finishEdit?.(); return set; })} |
