diff options
Diffstat (limited to 'src/client/views/collections')
7 files changed, 67 insertions, 39 deletions
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index f3397e2c4..99a68e94b 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -372,7 +372,8 @@ .editableView-container-editing-oneLine, .editableView-container-editing { color: grey; - padding-top: 10px; + padding-top: 5px; + padding-bottom: 5px; width: 100%; } @@ -387,7 +388,8 @@ letter-spacing: 2px; color: grey; border: 0px; - padding-top: 10px; // 12px 10px 11px 10px; + padding-top: 5px; // 12px 10px 11px 10px; + padding-bottom: 5px; // 12px 10px 11px 10px; } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 29bdc0e2d..08e3174d1 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -53,7 +53,6 @@ import { MarqueeView } from './MarqueeView'; import React = require('react'); export type collectionFreeformViewProps = { - noPointerWheel?: () => boolean; // turn off pointerwheel interactions (see PDFViewer) NativeWidth?: () => number; NativeHeight?: () => number; originTopLeft?: boolean; @@ -1023,13 +1022,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection deltaScale = 20 / invTransform.Scale; } if (deltaScale < 1 && invTransform.Scale <= NumCast(this.rootDoc._viewScaleMin, 1) && this.isAnnotationOverlay) { + this.setPan(0, 0); return; } if (deltaScale * invTransform.Scale < NumCast(this.rootDoc._viewScaleMin, 1) && this.isAnnotationOverlay) { deltaScale = NumCast(this.rootDoc._viewScaleMin, 1) / invTransform.Scale; } - const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y); + const localTransform = invTransform.scaleAbout(deltaScale, x, y); if (localTransform.Scale >= 0.05 || localTransform.Scale > this.zoomScaling()) { const safeScale = Math.min(Math.max(0.05, localTransform.Scale), 20); this.props.Document[this.scaleFieldKey] = Math.abs(safeScale); @@ -1039,17 +1039,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @action onPointerWheel = (e: React.WheelEvent): void => { - if (this.props.noPointerWheel?.() || this.Document._isGroup || !this.isContentActive()) return; // group style collections neither pan nor zoom + if (this.Document._isGroup || !this.isContentActive()) return; // group style collections neither pan nor zoom PresBox.Instance?.pauseAutoPres(); if (this.layoutDoc._Transform || DocListCast(Doc.MyOverlayDocs?.data).includes(this.props.Document) || this.props.Document.treeViewOutlineMode === TreeViewType.outline) return; e.stopPropagation(); - e.preventDefault(); switch (!e.ctrlKey ? Doc.UserDoc().freeformScrollMode : freeformScrollMode.Pan) { case freeformScrollMode.Pan: // if ctrl is selected then zoom if (e.ctrlKey) { if (this.props.isContentActive(true)) { - this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc? + if (this.props.isAnnotationOverlayScrollable) { + // bcz: zooming on a webbox doesn't get the correct coordinates here for unknown reasons. + // so better to do nothing than having things jump around. + } else this.zoom(e.screenX, e.screenY, e.deltaY); } } // otherwise pan else if (this.props.isContentActive(true)) { @@ -1123,16 +1125,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection (1 - minScale / scale) * NumCast(this.rootDoc._panYMax, nativeHeight) + (!this.props.getScrollHeight?.() ? fitYscroll : 0); // when not zoomed, scrolling is handled via a scrollbar, not panning let newPanY = Math.max(minPanY, Math.min(maxPanY, panY)); - if (NumCast(this.rootDoc.scrollTop) && NumCast(this.rootDoc._viewScale, minScale) !== minScale) { + if (false && NumCast(this.rootDoc.scrollTop) && NumCast(this.rootDoc._viewScale, minScale) !== minScale) { const relTop = NumCast(this.rootDoc.scrollTop) / maxScrollTop; this.rootDoc.scrollTop = undefined; newPanY = minPanY + relTop * (maxPanY - minPanY); } else if (fitYscroll && this.rootDoc.scrollTop === undefined && NumCast(this.rootDoc._viewScale, minScale) === minScale) { const maxPanY = minPanY + fitYscroll; const relTop = (panY - minPanY) / (maxPanY - minPanY); - setTimeout(() => { - this.rootDoc.scrollTop = relTop * maxScrollTop; - }, 10); + setTimeout(() => (this.rootDoc.scrollTop = relTop * maxScrollTop), 10); newPanY = minPanY; } !this.Document._verticalScroll && (this.Document[this.panXFieldKey] = this.isAnnotationOverlay ? newPanX : panX); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index a9434fde3..3a0c2c85c 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -182,8 +182,10 @@ .schema-table-cell, .row-menu { border: 1px solid $medium-gray; - overflow: hidden; + overflow-x: hidden; + overflow-y: auto; padding: 5px; + display: inline-block; } .schema-row { diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index a59d7e5a3..588affc1c 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -56,7 +56,8 @@ export class CollectionSchemaView extends CollectionSubView() { private _documentOptions: DocumentOptions = new DocumentOptions(); private _tableContentRef: HTMLDivElement | null = null; - public static _rowHeight: number = 50; + static _rowHeight: number = 50; + static _rowSingleLineHeight: number = 32; public static _minColWidth: number = 25; public static _rowMenuWidth: number = 60; public static _previewDividerWidth: number = 4; @@ -515,9 +516,9 @@ export class CollectionSchemaView extends CollectionSubView() { if (found) { const rect = found.getBoundingClientRect(); const localRect = this.props.ScreenToLocalTransform().transformBounds(rect.left, rect.top, rect.width, rect.height); - if (localRect.y < CollectionSchemaView._rowHeight || localRect.y + localRect.height > this.props.PanelHeight()) { + if (localRect.y < this.rowHeightFunc() || localRect.y + localRect.height > this.props.PanelHeight()) { let focusSpeed = options.zoomTime ?? 50; - smoothScroll(focusSpeed, this._tableContentRef!, localRect.y + this._tableContentRef!.scrollTop - CollectionSchemaView._rowHeight, options.easeFunc); + smoothScroll(focusSpeed, this._tableContentRef!, localRect.y + this._tableContentRef!.scrollTop - this.rowHeightFunc(), options.easeFunc); return focusSpeed; } } @@ -836,6 +837,7 @@ export class CollectionSchemaView extends CollectionSubView() { }); return { docs }; } + rowHeightFunc = () => (BoolCast(this.layoutDoc._singleLine) ? CollectionSchemaView._rowSingleLineHeight : CollectionSchemaView._rowHeight); sortedDocsFunc = () => this.sortedDocs; isContentActive = () => this.props.isSelected() || this.props.isContentActive(); screenToLocal = () => this.props.ScreenToLocalTransform().translate(-this.tableWidth, 0); @@ -850,7 +852,7 @@ export class CollectionSchemaView extends CollectionSubView() { // prevent wheel events from passively propagating up through containers r?.addEventListener('wheel', (e: WheelEvent) => {}, { passive: false }); }}> - <div className="schema-header-row" style={{ height: CollectionSchemaView._rowHeight }}> + <div className="schema-header-row" style={{ height: this.rowHeightFunc() }}> <div className="row-menu" style={{ width: CollectionSchemaView._rowMenuWidth }}> <div className="schema-header-button" onPointerDown={e => (this._columnMenuIndex === -1 ? this.closeColumnMenu() : this.openColumnMenu(-1, true))}> <FontAwesomeIcon icon="plus" /> @@ -865,6 +867,7 @@ export class CollectionSchemaView extends CollectionSubView() { sortField={this.sortField} sortDesc={this.sortDesc} setSort={this.setSort} + rowHeight={this.rowHeightFunc} removeColumn={this.removeColumn} resizeColumn={this.startResize} openContextMenu={this.openContextMenu} @@ -875,7 +878,7 @@ export class CollectionSchemaView extends CollectionSubView() { </div> {this._columnMenuIndex !== undefined && this.renderColumnMenu} {this._filterColumnIndex !== undefined && this.renderFilterMenu} - <CollectionSchemaViewDocs schema={this} childDocs={this.sortedDocsFunc} setRef={(ref: HTMLDivElement | null) => (this._tableContentRef = ref)} /> + <CollectionSchemaViewDocs schema={this} childDocs={this.sortedDocsFunc} rowHeight={this.rowHeightFunc} setRef={(ref: HTMLDivElement | null) => (this._tableContentRef = ref)} /> <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} height={CollectionSchemaView._newNodeInputHeight} /> </div> {this.previewWidth > 0 && <div className="schema-preview-divider" style={{ width: CollectionSchemaView._previewDividerWidth }} onPointerDown={this.onDividerDown}></div>} @@ -922,20 +925,20 @@ interface CollectionSchemaViewDocsProps { schema: CollectionSchemaView; setRef: (ref: HTMLDivElement | null) => void; childDocs: () => { docs: Doc[] }; + rowHeight: () => number; } @observer class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsProps> { tableWidthFunc = () => this.props.schema.tableWidth; - rowHeightFunc = () => CollectionSchemaView._rowHeight; - childScreenToLocal = computedFn((index: number) => () => this.props.schema.props.ScreenToLocalTransform().translate(0, -CollectionSchemaView._rowHeight - index * this.rowHeightFunc())); + childScreenToLocal = computedFn((index: number) => () => this.props.schema.props.ScreenToLocalTransform().translate(0, -this.props.rowHeight() - index * this.props.rowHeight())); render() { return ( - <div className="schema-table-content" ref={this.props.setRef} style={{ height: `calc(100% - ${CollectionSchemaView._newNodeInputHeight + CollectionSchemaView._rowHeight}px)` }}> + <div className="schema-table-content" ref={this.props.setRef} style={{ height: `calc(100% - ${CollectionSchemaView._newNodeInputHeight + this.props.rowHeight()}px)` }}> {this.props.childDocs().docs.map((doc: Doc, index: number) => { const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.schema.props.DataDoc; return ( - <div className="schema-row-wrapper" style={{ height: CollectionSchemaView._rowHeight }}> + <div className="schema-row-wrapper" style={{ height: this.props.rowHeight() }}> <DocumentView key={doc[Id]} {...this.props.schema.props} @@ -945,7 +948,7 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP DataDoc={dataDoc} renderDepth={this.props.schema.props.renderDepth + 1} PanelWidth={this.tableWidthFunc} - PanelHeight={this.rowHeightFunc} + PanelHeight={this.props.rowHeight} styleProvider={DefaultStyleProvider} waitForDoubleClickToClick={returnNever} defaultDoubleClick={returnIgnore} diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 243fe0c61..7da3c042c 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -16,6 +16,7 @@ export interface SchemaColumnHeaderProps { sortDesc: boolean; setSort: (field: string | undefined, desc?: boolean) => void; removeColumn: (index: number) => void; + rowHeight: () => number; resizeColumn: (e: any, index: number) => void; dragColumn: (e: any, index: number) => boolean; openContextMenu: (x: number, y: number, index: number) => void; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index ca9e0bda0..34631e0b7 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -2,6 +2,9 @@ import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; +import { computedFn } from 'mobx-utils'; +import { Doc } from '../../../../fields/Doc'; +import { BoolCast } from '../../../../fields/Types'; import { DragManager } from '../../../util/DragManager'; import { SnappingManager } from '../../../util/SnappingManager'; import { undoBatch } from '../../../util/UndoManager'; @@ -12,8 +15,6 @@ import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { CollectionSchemaView } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; import { SchemaTableCell } from './SchemaTableCell'; -import { computedFn } from 'mobx-utils'; -import { Doc } from '../../../../fields/Doc'; @observer export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() { @@ -95,7 +96,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() { return ( <div className="schema-row" - style={{ height: CollectionSchemaView._rowHeight, backgroundColor: this.props.isSelected() ? Colors.LIGHT_BLUE : undefined }} + style={{ height: this.props.PanelHeight(), backgroundColor: this.props.isSelected() ? Colors.LIGHT_BLUE : undefined }} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave} ref={(row: HTMLDivElement | null) => { @@ -132,13 +133,16 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() { Document={this.rootDoc} col={index} fieldKey={key} + allowCRs={false} // to enter text with new lines, must use \n columnWidth={this.columnWidth(index)} + rowHeight={this.schemaView.rowHeightFunc} isRowActive={this.props.isContentActive} getFinfo={this.getFinfo} selectCell={this.selectCell} deselectCell={this.deselectCell} selectedCell={this.selectedCell} setColumnValues={this.setColumnValues} + oneLine={BoolCast(this.schemaDoc?._singleLine)} /> ))} </div> diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 712bd4491..12daa1252 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -5,22 +5,24 @@ import { extname } from 'path'; import DatePicker from 'react-datepicker'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field } from '../../../../fields/Doc'; +import { RichTextField } from '../../../../fields/RichTextField'; import { BoolCast, Cast, DateCast, FieldValue } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero, Utils } from '../../../../Utils'; import { FInfo } from '../../../documents/Documents'; +import { DocFocusOrOpen } from '../../../util/DocumentManager'; import { dropActionType } from '../../../util/DragManager'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; +import { OpenWhere } from '../../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; +import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { KeyValueBox } from '../../nodes/KeyValueBox'; import { DefaultStyleProvider } from '../../StyleProvider'; -import { CollectionSchemaView, ColumnType, FInfotoColType } from './CollectionSchemaView'; +import { ColumnType, FInfotoColType } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; -import { RichTextField } from '../../../../fields/RichTextField'; -import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; export interface SchemaTableCellProps { Document: Doc; @@ -29,17 +31,24 @@ export interface SchemaTableCellProps { selectCell: (doc: Doc, col: number) => void; selectedCell: () => [Doc, number] | undefined; fieldKey: string; + maxWidth?: () => number; columnWidth: () => number; + rowHeight: () => number; + padding?: number; // default is 5 -- see scss isRowActive: () => boolean | undefined; getFinfo: (fieldKey: string) => FInfo | undefined; setColumnValues: (field: string, value: string) => boolean; + oneLine?: boolean; // whether all input should fit on one line vs allowing textare multiline inputs + allowCRs?: boolean; // allow carriage returns in text input (othewrise CR ends the edit) + finishEdit?: () => void; // notify container that edit is over (eg. to hide view in DashFieldView) } @observer export class SchemaTableCell extends React.Component<SchemaTableCellProps> { - public static colRowHeightFunc() { - return CollectionSchemaView._rowHeight; - } + static addFieldDoc = (doc: Doc, where: OpenWhere) => { + DocFocusOrOpen(doc); + return true; + }; public static renderProps(props: SchemaTableCellProps) { const { Document, fieldKey, getFinfo, columnWidth, isRowActive } = props; let protoCount = 0; @@ -71,12 +80,12 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { whenChildContentsActiveChanged: emptyFunction, ScreenToLocalTransform: Transform.Identity, focus: emptyFunction, - addDocTab: returnFalse, + addDocTab: SchemaTableCell.addFieldDoc, pinToPres: returnZero, Document, fieldKey, PanelWidth: columnWidth, - PanelHeight: SchemaTableCell.colRowHeightFunc, + PanelHeight: props.rowHeight, }; const readOnly = getFinfo(fieldKey)?.readOnly ?? false; const cursor = !readOnly ? 'text' : 'default'; @@ -98,8 +107,11 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { style={{ color, textDecoration, + width: '100%', }}> <EditableView + oneLine={this.props.oneLine} + allowCRs={this.props.allowCRs} contents={<FieldView {...fieldProps} />} editing={this.selected ? undefined : false} GetValue={() => Field.toKeyValueString(this.props.Document, this.props.fieldKey)} @@ -107,7 +119,9 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { if (shiftDown && enterKey) { this.props.setColumnValues(this.props.fieldKey.replace(/^_/, ''), value); } - return KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value); + const ret = KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value); + this.props.finishEdit?.(); + return ret; })} /> </div> @@ -121,7 +135,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { if (cellValue instanceof RichTextField) return ColumnType.RTF; if (typeof cellValue === 'number') return ColumnType.Any; if (typeof cellValue === 'string') return ColumnType.Any; - if (typeof cellValue === 'boolean') return ColumnType.Any; + if (typeof cellValue === 'boolean') return ColumnType.Boolean; const columnTypeStr = this.props.getFinfo(this.props.fieldKey)?.fieldType; if (columnTypeStr && columnTypeStr in FInfotoColType) { @@ -148,7 +162,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> { <div className="schema-table-cell" onPointerDown={action(e => !this.selected && this.props.selectCell(this.props.Document, this.props.col))} - style={{ width: this.props.columnWidth(), border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> + style={{ padding: this.props.padding, maxWidth: this.props.maxWidth?.(), width: this.props.columnWidth() || undefined, border: this.selected ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined }}> {this.content} </div> ); @@ -211,8 +225,8 @@ export class SchemaImageCell extends React.Component<SchemaTableCellProps> { const aspect = Doc.NativeAspect(this.props.Document); // aspect ratio // let width = Math.max(75, this.props.columnWidth); // get a with that is no smaller than 75px // const height = Math.max(75, width / aspect); // get a height either proportional to that or 75 px - const height = CollectionSchemaView._rowHeight - 10; - const width = height * aspect; // increase the width of the image if necessary to maintain proportionality + const height = this.props.rowHeight() ? this.props.rowHeight() - (this.props.padding || 6) * 2 : undefined; + const width = height ? height * aspect : undefined; // increase the width of the image if necessary to maintain proportionality return <img src={this.url} width={width} height={height} style={{}} draggable="false" onPointerEnter={this.showHoverPreview} onPointerMove={this.moveHoverPreview} onPointerLeave={this.removeHoverPreview} />; } @@ -288,7 +302,9 @@ export class SchemaBoolCell extends React.Component<SchemaTableCellProps> { if (shiftDown && enterKey) { this.props.setColumnValues(this.props.fieldKey.replace(/^_/, ''), value); } - return KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value); + const set = KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value); + this.props.finishEdit?.(); + return set; })} /> </div> |
