aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionSchema
diff options
context:
space:
mode:
authorEric <ericmabr@gmail.com>2023-08-13 16:08:28 -0400
committerEric <ericmabr@gmail.com>2023-08-13 16:08:28 -0400
commit0020ec69b847c8607affb57babddfddc812dc9b6 (patch)
treee24255039015745d2073806bee97ce449ddb5260 /src/client/views/collections/collectionSchema
parent7b2553514bb000eb7f618eb0f0d653baee78742c (diff)
parent3b45f1d30a947dc1702ec347b83e98374c5b603c (diff)
Merge branch 'master' into UI_Update_Eric_Ma
Diffstat (limited to 'src/client/views/collections/collectionSchema')
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.scss2
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx119
-rw-r--r--src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx5
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx26
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTableCell.tsx67
5 files changed, 131 insertions, 88 deletions
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index 3a0c2c85c..52ebb7763 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -104,7 +104,7 @@
.schema-header-row {
cursor: grab;
- justify-content: flex-end;
+ //justify-content: flex-end;
.row-menu {
display: flex;
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index bcc2ca129..babe5c810 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -8,17 +8,16 @@ import { Id } from '../../../../fields/FieldSymbols';
import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnDefault, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
+import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { SelectionManager } from '../../../util/SelectionManager';
-import { undoBatch } from '../../../util/UndoManager';
+import { undoable, undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
import { DocFocusOptions, DocumentView } from '../../nodes/DocumentView';
-import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { KeyValueBox } from '../../nodes/KeyValueBox';
import { DefaultStyleProvider } from '../../StyleProvider';
import { CollectionSubView } from '../CollectionSubView';
@@ -33,6 +32,7 @@ export enum ColumnType {
Date,
Image,
RTF,
+ Enumeration,
Any,
}
@@ -43,9 +43,10 @@ export const FInfotoColType: { [key: string]: ColumnType } = {
date: ColumnType.Date,
image: ColumnType.Image,
rtf: ColumnType.RTF,
+ enumeration: ColumnType.Enumeration,
};
-const defaultColumnKeys: string[] = ['title', 'type', 'author', 'creationDate', 'text'];
+const defaultColumnKeys: string[] = ['title', 'type', 'author', 'author_date', 'text'];
@observer
export class CollectionSchemaView extends CollectionSubView() {
@@ -55,6 +56,7 @@ export class CollectionSchemaView extends CollectionSubView() {
private _makeNewColumn: boolean = false;
private _documentOptions: DocumentOptions = new DocumentOptions();
private _tableContentRef: HTMLDivElement | null = null;
+ private _menuTarget = React.createRef<HTMLDivElement>();
static _rowHeight: number = 50;
static _rowSingleLineHeight: number = 32;
@@ -78,6 +80,11 @@ export class CollectionSchemaView extends CollectionSubView() {
@observable _filterSearchValue: string = '';
@observable _selectedCell: [Doc, number] | undefined;
+ // target HTMLelement portal for showing a popup menu to edit cell values.
+ public get MenuTarget() {
+ return this._menuTarget.current;
+ }
+
@computed get _selectedDocs() {
return SelectionManager.Docs().filter(doc => Doc.AreProtosEqual(DocCast(doc.embedContainer), this.rootDoc));
}
@@ -224,7 +231,7 @@ export class CollectionSchemaView extends CollectionSubView() {
@undoBatch
@action
- setSort = (field: string | undefined, desc: boolean = false) => {
+ setColumnSort = (field: string | undefined, desc: boolean = false) => {
this.layoutDoc.sortField = field;
this.layoutDoc.sortDesc = desc;
};
@@ -337,9 +344,7 @@ export class CollectionSchemaView extends CollectionSubView() {
dragColumn = (e: PointerEvent, index: number) => {
const dragData = new DragManager.ColumnDragData(index);
const dragEles = [this._colEles[index]];
- this.childDocs.forEach(doc => {
- dragEles.push(this._rowEles.get(doc).children[1].children[index]);
- });
+ this.childDocs.forEach(doc => dragEles.push(this._rowEles.get(doc).children[1].children[index]));
DragManager.StartColumnDrag(dragEles, dragData, e.x, e.y);
document.removeEventListener('pointermove', this.highlightDropColumn);
@@ -353,24 +358,28 @@ export class CollectionSchemaView extends CollectionSubView() {
return true;
};
- @action
- highlightDropColumn = (e: PointerEvent) => {
- e.stopPropagation();
- const mouseX = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0];
+ findDropIndex = (mouseX: number) => {
let index: number | undefined;
this.displayColumnWidths.reduce((total, curr, i) => {
if (total <= mouseX && total + curr >= mouseX) {
- if (mouseX <= total + curr / 2) index = i;
+ if (mouseX <= total + curr) index = i;
else index = i + 1;
}
return total + curr;
}, CollectionSchemaView._rowMenuWidth);
+ return index;
+ };
+ @action
+ highlightDropColumn = (e: PointerEvent) => {
+ e.stopPropagation();
+ const mouseX = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0];
+ const index = this.findDropIndex(mouseX);
this._colEles.forEach((colRef, i) => {
let leftStyle = '';
let rightStyle = '';
- if (i + 1 === index) rightStyle = `solid 2px ${Colors.MEDIUM_BLUE}`;
- if (i === index && i === 0) leftStyle = `solid 2px ${Colors.MEDIUM_BLUE}`;
+ if (i + 1 === index) rightStyle = `solid 12px ${Colors.MEDIUM_BLUE}`;
+ if (i === index && i === 0) leftStyle = `solid 12px ${Colors.MEDIUM_BLUE}`;
colRef.style.borderLeft = leftStyle;
colRef.style.borderRight = rightStyle;
this.childDocs.forEach(doc => {
@@ -425,17 +434,9 @@ export class CollectionSchemaView extends CollectionSubView() {
@action
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.columnDragData) {
- e.stopPropagation();
const mouseX = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0];
- let index = de.complete.columnDragData.colIndex;
- this.displayColumnWidths.reduce((total, curr, i) => {
- if (total <= mouseX && total + curr >= mouseX) {
- if (mouseX <= total + curr / 2) index = i;
- else index = i + 1;
- }
- return total + curr;
- }, CollectionSchemaView._rowMenuWidth);
- this.moveColumn(de.complete.columnDragData.colIndex, index);
+ const index = this.findDropIndex(mouseX);
+ this.moveColumn(de.complete.columnDragData.colIndex, index ?? de.complete.columnDragData.colIndex);
this._colEles.forEach((colRef, i) => {
colRef.style.borderLeft = '';
@@ -446,6 +447,7 @@ export class CollectionSchemaView extends CollectionSubView() {
});
});
+ e.stopPropagation();
return true;
}
const draggedDocs = de.complete.docDragData?.draggedDocuments;
@@ -460,7 +462,6 @@ export class CollectionSchemaView extends CollectionSubView() {
if (draggedView) DocumentManager.Instance.RemoveView(draggedView);
DocumentManager.Instance.AddViewRenderedCb(doc, dv => dv.select(true));
});
- e.stopPropagation();
return true;
}
return false;
@@ -484,24 +485,11 @@ export class CollectionSchemaView extends CollectionSubView() {
return false;
};
- @action
- addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
- if (!value && !forceEmptyNote) return false;
- const newDoc = Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true });
- FormattedTextBox.SelectOnLoad = newDoc[Id];
- FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
- return this.addRow(newDoc) || false;
- };
-
menuCallback = (x: number, y: number) => {
ContextMenu.Instance.clearItems();
- DocUtils.addDocumentCreatorMenuItems(doc => this.addRow(doc), this.addRow, x, y, true);
+ DocUtils.addDocumentCreatorMenuItems(this.addRow, this.addRow, x, y, true);
- ContextMenu.Instance.setDefaultItem('::', (name: string): void => {
- Doc.GetProto(this.props.Document)[name] = '';
- this.addRow(Docs.Create.TextDocument('', { title: name, _layout_autoHeight: true }));
- });
ContextMenu.Instance.displayMenu(x, y, undefined, true);
};
@@ -621,7 +609,7 @@ export class CollectionSchemaView extends CollectionSubView() {
this._menuKeys = this.documentKeys.filter(value => value.toLowerCase().includes(this._menuValue.toLowerCase()));
};
- getFieldFilters = (field: string) => StrListCast(this.Document._docFilters).filter(filter => filter.split(':')[0] == field);
+ getFieldFilters = (field: string) => StrListCast(this.Document._childFilters).filter(filter => filter.split(':')[0] == field);
removeFieldFilters = (field: string) => {
this.getFieldFilters(field).forEach(filter => Doc.setDocFilter(this.Document, field, filter.split(':')[1], 'remove'));
@@ -697,6 +685,12 @@ export class CollectionSchemaView extends CollectionSubView() {
);
}
+ onPassiveWheel = (e: WheelEvent) => {
+ // if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this)
+ if (!this._oldWheel.scrollTop && e.deltaY <= 0) e.preventDefault();
+ e.stopPropagation();
+ };
+ _oldWheel: any;
@computed get keysDropdown() {
return (
<div className="schema-key-search">
@@ -710,16 +704,11 @@ export class CollectionSchemaView extends CollectionSubView() {
</div>
<div
className="schema-key-list"
- ref={r =>
- r?.addEventListener(
- 'wheel', // if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this)
- (e: WheelEvent) => {
- if (!r.scrollTop && e.deltaY <= 0) e.preventDefault();
- e.stopPropagation();
- },
- { passive: false }
- )
- }>
+ ref={r => {
+ this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel);
+ this._oldWheel = r;
+ r?.addEventListener('wheel', this.onPassiveWheel, { passive: false });
+ }}>
{this._menuKeys.map(key => (
<div
className="schema-search-result"
@@ -773,7 +762,7 @@ export class CollectionSchemaView extends CollectionSubView() {
}
});
- const filters = StrListCast(this.Document._docFilters);
+ const filters = StrListCast(this.Document._childFilters);
return keyOptions.map(key => {
let bool = false;
if (filters !== undefined) {
@@ -821,7 +810,6 @@ export class CollectionSchemaView extends CollectionSubView() {
}
@computed get sortedDocs() {
- trace();
const field = StrCast(this.layoutDoc.sortField);
const desc = BoolCast(this.layoutDoc.sortDesc);
const docs = !field
@@ -845,6 +833,7 @@ export class CollectionSchemaView extends CollectionSubView() {
render() {
return (
<div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)}>
+ <div ref={this._menuTarget} style={{ background: 'red', top: 0, left: 0, position: 'absolute', zIndex: 10000 }}></div>
<div
className="schema-table"
onWheel={e => this.props.isContentActive() && e.stopPropagation()}
@@ -866,20 +855,28 @@ export class CollectionSchemaView extends CollectionSubView() {
columnWidths={this.displayColumnWidths}
sortField={this.sortField}
sortDesc={this.sortDesc}
- setSort={this.setSort}
+ setSort={this.setColumnSort}
rowHeight={this.rowHeightFunc}
removeColumn={this.removeColumn}
resizeColumn={this.startResize}
openContextMenu={this.openContextMenu}
dragColumn={this.dragColumn}
setColRef={this.setColRef}
+ isContentActive={this.props.isContentActive}
/>
))}
</div>
{this._columnMenuIndex !== undefined && this.renderColumnMenu}
{this._filterColumnIndex !== undefined && this.renderFilterMenu}
<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} />
+ <EditableView
+ GetValue={returnEmptyString}
+ SetValue={undoable(value => (value ? this.addRow(Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true })) : false), 'add text doc')}
+ 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>}
{this.previewWidth > 0 && (
@@ -900,8 +897,8 @@ export class CollectionSchemaView extends CollectionSubView() {
isContentActive={returnTrue}
isDocumentActive={returnFalse}
ScreenToLocalTransform={this.screenToLocal}
- docFilters={this.childDocFilters}
- docRangeFilters={this.childDocRangeFilters}
+ childFilters={this.childDocFilters}
+ childFiltersByRanges={this.childDocRangeFilters}
searchFilterDocs={this.searchFilterDocs}
styleProvider={DefaultStyleProvider}
docViewPath={returnEmptyDoclist}
@@ -946,17 +943,18 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP
LayoutTemplateString={SchemaRowBox.LayoutString(this.props.schema.props.fieldKey)}
Document={doc}
DataDoc={dataDoc}
+ yPadding={index}
renderDepth={this.props.schema.props.renderDepth + 1}
PanelWidth={this.tableWidthFunc}
PanelHeight={this.props.rowHeight}
styleProvider={DefaultStyleProvider}
waitForDoubleClickToClick={returnNever}
defaultDoubleClick={returnIgnore}
- enableDragWhenActive={true}
+ dragAction="move"
onClickScriptDisable="always"
focus={this.props.schema.focusDocument}
- docFilters={this.props.schema.childDocFilters}
- docRangeFilters={this.props.schema.childDocRangeFilters}
+ childFilters={this.props.schema.childDocFilters}
+ childFiltersByRanges={this.props.schema.childDocRangeFilters}
searchFilterDocs={this.props.schema.searchFilterDocs}
rootSelected={this.props.schema.rootSelected}
ScreenToLocalTransform={this.childScreenToLocal(index)}
@@ -970,7 +968,6 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP
hideLinkAnchors={true}
layout_fitWidth={returnTrue}
scriptContext={this}
- canEmbedOnDrag={true}
/>
</div>
);
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 7da3c042c..65e47f441 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -5,8 +5,6 @@ import { observer } from 'mobx-react';
import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
import { Colors } from '../../global/globalEnums';
import './CollectionSchemaView.scss';
-import { SnappingManager } from '../../../util/SnappingManager';
-import { DragManager } from '../../../util/DragManager';
export interface SchemaColumnHeaderProps {
columnKeys: string[];
@@ -14,6 +12,7 @@ export interface SchemaColumnHeaderProps {
columnIndex: number;
sortField: string;
sortDesc: boolean;
+ isContentActive: (outsideReaction?: boolean | undefined) => boolean | undefined;
setSort: (field: string | undefined, desc?: boolean) => void;
removeColumn: (index: number) => void;
rowHeight: () => number;
@@ -46,7 +45,7 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
@action
onPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, e => this.props.dragColumn(e, this.props.columnIndex), emptyFunction, emptyFunction, false);
+ this.props.isContentActive(true) && setupMoveUpEvents(this, e, e => this.props.dragColumn(e, this.props.columnIndex), emptyFunction, emptyFunction, false);
};
render() {
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 45bfe4f77..e8e606030 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -7,7 +7,7 @@ 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';
+import { undoable } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { OpenWhere } from '../../nodes/DocumentView';
@@ -15,6 +15,7 @@ import { FieldView, FieldViewProps } from '../../nodes/FieldView';
import { CollectionSchemaView } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
import { SchemaTableCell } from './SchemaTableCell';
+import { Transform } from '../../../util/Transform';
@observer
export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
@@ -52,13 +53,13 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
onPointerEnter = (e: any) => {
- if (!SnappingManager.GetIsDragging()) return;
- document.removeEventListener('pointermove', this.onPointerMove);
- document.addEventListener('pointermove', this.onPointerMove);
+ if (SnappingManager.GetIsDragging() && this.props.isContentActive()) {
+ document.removeEventListener('pointermove', this.onPointerMove);
+ document.addEventListener('pointermove', this.onPointerMove);
+ }
};
onPointerMove = (e: any) => {
- if (!SnappingManager.GetIsDragging()) return;
const dragIsRow = DragManager.docsBeingDragged.some(doc => doc.embedContainer === this.schemaDoc); // this.schemaView?._selectedDocs.has(doc) ?? false;
if (this._ref && dragIsRow) {
@@ -111,18 +112,18 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
}}>
<div
className="schema-row-button"
- onPointerDown={undoBatch(e => {
+ onPointerDown={undoable(e => {
e.stopPropagation();
this.props.removeDocument?.(this.rootDoc);
- })}>
+ }, 'Delete Row')}>
<FontAwesomeIcon icon="times" />
</div>
<div
className="schema-row-button"
- onPointerDown={e => {
+ onPointerDown={undoable(e => {
e.stopPropagation();
this.props.addDocTab(this.rootDoc, OpenWhere.addRight);
- }}>
+ }, 'Open Doc on Right')}>
<FontAwesomeIcon icon="external-link-alt" />
</div>
</div>
@@ -143,6 +144,13 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
selectedCell={this.selectedCell}
setColumnValues={this.setColumnValues}
oneLine={BoolCast(this.schemaDoc?._singleLine)}
+ menuTarget={this.schemaView.MenuTarget}
+ transform={() => {
+ const ind = index === this.schemaView.columnKeys.length - 1 ? this.schemaView.columnKeys.length - 3 : index;
+ const x = this.schemaView?.displayColumnWidths.reduce((p, c, i) => (i <= ind ? p + c : p), 0);
+ const y = (this.props.yPadding ?? 0) * this.props.PanelHeight();
+ return new Transform(x + CollectionSchemaView._rowMenuWidth, y, 1);
+ }}
/>
))}
</div>
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 42bf32475..1c9c0de53 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -1,4 +1,5 @@
-import React = require('react');
+import * as React from 'react';
+import Select, { MenuPlacement } from 'react-select';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import { extname } from 'path';
@@ -6,14 +7,13 @@ 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 { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast } 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 { undoable, undoBatch } from '../../../util/UndoManager';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
import { OpenWhere } from '../../nodes/DocumentView';
@@ -21,7 +21,7 @@ import { FieldView, FieldViewProps } from '../../nodes/FieldView';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { KeyValueBox } from '../../nodes/KeyValueBox';
import { DefaultStyleProvider } from '../../StyleProvider';
-import { ColumnType, FInfotoColType } from './CollectionSchemaView';
+import { CollectionSchemaView, ColumnType, FInfotoColType } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
export interface SchemaTableCellProps {
@@ -41,6 +41,9 @@ export interface SchemaTableCellProps {
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)
+ options?: string[];
+ menuTarget: HTMLDivElement | null;
+ transform: () => Transform;
}
@observer
@@ -58,14 +61,14 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
break;
}
protoCount++;
- doc = doc.proto;
+ doc = DocCast(doc.proto);
}
const parenCount = Math.max(0, protoCount - 1);
const color = protoCount === 0 || (fieldKey.startsWith('_') && Document[fieldKey] === undefined) ? 'black' : 'blue';
const textDecoration = color !== 'black' && parenCount ? 'underline' : '';
const fieldProps: FieldViewProps = {
- docFilters: returnEmptyFilter,
- docRangeFilters: returnEmptyFilter,
+ childFilters: returnEmptyFilter,
+ childFiltersByRanges: returnEmptyFilter,
searchFilterDocs: returnEmptyDoclist,
styleProvider: DefaultStyleProvider,
docViewPath: returnEmptyDoclist,
@@ -73,7 +76,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
isSelected: returnFalse,
setHeight: returnFalse,
select: emptyFunction,
- dropAction: 'embed',
+ dragAction: 'move',
bringToFront: emptyFunction,
renderDepth: 1,
isContentActive: returnFalse,
@@ -115,29 +118,29 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
contents={<FieldView {...fieldProps} />}
editing={this.selected ? undefined : false}
GetValue={() => Field.toKeyValueString(this.props.Document, this.props.fieldKey)}
- SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => {
+ SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => {
if (shiftDown && enterKey) {
this.props.setColumnValues(this.props.fieldKey.replace(/^_/, ''), value);
}
const ret = KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value);
this.props.finishEdit?.();
return ret;
- })}
+ }, 'edit schema cell')}
/>
</div>
);
}
get getCellType() {
+ const columnTypeStr = this.props.getFinfo(this.props.fieldKey)?.fieldType;
const cellValue = this.props.Document[this.props.fieldKey];
if (cellValue instanceof ImageField) return ColumnType.Image;
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') return ColumnType.Any;
+ if (typeof cellValue === 'string' && columnTypeStr !== 'enumeration') return ColumnType.Any;
if (typeof cellValue === 'boolean') return ColumnType.Boolean;
- const columnTypeStr = this.props.getFinfo(this.props.fieldKey)?.fieldType;
if (columnTypeStr && columnTypeStr in FInfotoColType) {
return FInfotoColType[columnTypeStr];
}
@@ -152,6 +155,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
case ColumnType.Image: return <SchemaImageCell {...this.props} />;
case ColumnType.Boolean: return <SchemaBoolCell {...this.props} />;
case ColumnType.RTF: return <SchemaRTFCell {...this.props} />;
+ case ColumnType.Enumeration: return <SchemaEnumerationCell {...this.props} options={this.props.getFinfo(this.props.fieldKey)?.values?.map(val => val.toString())} />;
case ColumnType.Date: // return <SchemaDateCell {...this.props} />;
default: return this.defaultCellContent;
}
@@ -268,7 +272,7 @@ export class SchemaRTFCell extends React.Component<SchemaTableCellProps> {
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 allowScroll={true} {...fieldProps} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
+ {this.selected ? <FormattedTextBox allowScroll={true} {...fieldProps} DataDoc={this.props.Document} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
</div>
);
}
@@ -311,3 +315,38 @@ export class SchemaBoolCell extends React.Component<SchemaTableCellProps> {
);
}
}
+@observer
+export class SchemaEnumerationCell extends React.Component<SchemaTableCellProps> {
+ @computed get selected() {
+ const selected: [Doc, number] | undefined = this.props.selectedCell();
+ return this.props.isRowActive() && selected?.[0] === this.props.Document && selected[1] === this.props.col;
+ }
+ render() {
+ const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this.props);
+ const options = this.props.options?.map(facet => ({ value: facet, label: facet }));
+ return (
+ <div className="schemaSelectionCell" style={{ display: 'flex', color, textDecoration, cursor, pointerEvents }}>
+ <div style={{ width: '100%' }}>
+ <Select
+ styles={{
+ menuPortal: base => ({
+ ...base,
+ left: 0,
+ top: 0,
+ transform: `translate(${this.props.transform().TranslateX}px, ${this.props.transform().TranslateY}px)`,
+ width: Number(base.width) * this.props.transform().Scale,
+ zIndex: 9999,
+ }),
+ }}
+ menuPortalTarget={this.props.menuTarget}
+ menuPosition={'absolute'}
+ placeholder={StrCast(this.props.Document[this.props.fieldKey], 'select...')}
+ options={options}
+ isMulti={false}
+ onChange={val => KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)}
+ />
+ </div>
+ </div>
+ );
+ }
+}