aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-12-21 14:55:48 -0500
committerbobzel <zzzman@gmail.com>2023-12-21 14:55:48 -0500
commit1caba64ee0f32ee8af79263cd4ef2a8bc5d5146e (patch)
tree0fa0e957d1f342fdc6ed4a4b43f5dddfddb1298a /src/client/views/collections/CollectionMasonryViewFieldRow.tsx
parent02eb7da95df283606d4275a22d9451cef371c3b5 (diff)
parent2691b951d96f2ce7652acbea9e340b61737b3b57 (diff)
Merge branch 'moreUpgrading' into dataViz-annotations
Diffstat (limited to 'src/client/views/collections/CollectionMasonryViewFieldRow.tsx')
-rw-r--r--src/client/views/collections/CollectionMasonryViewFieldRow.tsx134
1 files changed, 61 insertions, 73 deletions
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 06522b85e..8627ba650 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -1,13 +1,12 @@
-import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
+import * as React from 'react';
+import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
-import { Id } from '../../../fields/FieldSymbols';
import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { ScriptField } from '../../../fields/ScriptField';
-import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils';
import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { CompileScript } from '../../util/Scripting';
@@ -15,12 +14,10 @@ import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
import { EditableView } from '../EditableView';
+import { ObservableReactComponent } from '../ObservableReactComponent';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { CollectionStackingView } from './CollectionStackingView';
import './CollectionStackingView.scss';
-const higflyout = require('@hig/flyout');
-export const { anchorPoints } = higflyout;
-export const Flyout = higflyout.default;
interface CMVFieldRowProps {
rows: () => number;
@@ -42,7 +39,12 @@ interface CMVFieldRowProps {
}
@observer
-export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowProps> {
+export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVFieldRowProps> {
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ }
+
@observable private _background = 'inherit';
@observable private _createEmbeddingSelected: boolean = false;
@observable private heading: string = '';
@@ -50,13 +52,13 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
@observable private collapsed: boolean = false;
@observable private _paletteOn = false;
private set _heading(value: string) {
- runInAction(() => this.props.headingObject && (this.props.headingObject.heading = this.heading = value));
+ runInAction(() => this._props.headingObject && (this._props.headingObject.heading = this.heading = value));
}
private set _color(value: string) {
- runInAction(() => this.props.headingObject && (this.props.headingObject.color = this.color = value));
+ runInAction(() => this._props.headingObject && (this._props.headingObject.color = this.color = value));
}
private set _collapsed(value: boolean) {
- runInAction(() => this.props.headingObject && (this.props.headingObject.collapsed = this.collapsed = value));
+ runInAction(() => this._props.headingObject && (this._props.headingObject.collapsed = this.collapsed = value));
}
private _dropDisposer?: DragManager.DragDropDisposer;
@@ -68,28 +70,28 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
this._dropDisposer?.();
if (ele) {
this._ele = ele;
- this.props.observeHeight(ele);
+ this._props.observeHeight(ele);
this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this));
}
};
@action
componentDidMount() {
- this.heading = this.props.headingObject?.heading || '';
- this.color = this.props.headingObject?.color || '#f1efeb';
- this.collapsed = this.props.headingObject?.collapsed || false;
+ this.heading = this._props.headingObject?.heading || '';
+ this.color = this._props.headingObject?.color || '#f1efeb';
+ this.collapsed = this._props.headingObject?.collapsed || false;
}
componentWillUnmount() {
- this.props.unobserveHeight(this._ele);
+ this._props.unobserveHeight(this._ele);
}
getTrueHeight = () => {
if (this.collapsed) {
- this.props.setDocHeight(this.heading, 20);
+ this._props.setDocHeight(this.heading, 20);
} else {
const rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; //+ 15 accounts for the group header
- const transformScale = this.props.screenToLocalTransform().Scale;
+ const transformScale = this._props.screenToLocalTransform().Scale;
const trueHeight = rawHeight * transformScale;
- this.props.setDocHeight(this.heading, trueHeight);
+ this._props.setDocHeight(this.heading, trueHeight);
}
};
@@ -97,10 +99,10 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
rowDrop = action((e: Event, de: DragManager.DropEvent) => {
this._createEmbeddingSelected = false;
if (de.complete.docDragData) {
- const key = this.props.pivotField;
+ const key = this._props.pivotField;
const castedValue = this.getValue(this.heading);
const onLayoutDoc = this.onLayoutDoc(key);
- if (this.props.parent.onInternalDrop(e, de)) {
+ if (this._props.parent.onInternalDrop(e, de)) {
de.complete.docDragData.droppedDocuments.forEach(d => Doc.SetInPlace(d, key, castedValue, !onLayoutDoc));
}
return true;
@@ -119,15 +121,15 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
@action
headingChanged = (value: string, shiftDown?: boolean) => {
this._createEmbeddingSelected = false;
- const key = this.props.pivotField;
+ const key = this._props.pivotField;
const castedValue = this.getValue(value);
if (castedValue) {
- if (this.props.parent.colHeaderData) {
- if (this.props.parent.colHeaderData.map(i => i.heading).indexOf(castedValue.toString()) > -1) {
+ if (this._props.parent.colHeaderData) {
+ if (this._props.parent.colHeaderData.map(i => i.heading).indexOf(castedValue.toString()) > -1) {
return false;
}
}
- this.props.docList.forEach(d => Doc.SetInPlace(d, key, castedValue, true));
+ this._props.docList.forEach(d => Doc.SetInPlace(d, key, castedValue, true));
this._heading = castedValue.toString();
return true;
}
@@ -140,7 +142,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
this._color = color;
};
- pointerEnteredRow = action(() => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4'));
+ pointerEnteredRow = action(() => SnappingManager.IsDragging && (this._background = '#b4b4b4'));
@action
pointerLeaveRow = () => {
@@ -152,24 +154,24 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
addDocument = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
if (!value && !forceEmptyNote) return false;
this._createEmbeddingSelected = false;
- const key = this.props.pivotField;
+ const key = this._props.pivotField;
const newDoc = Docs.Create.TextDocument('', { _layout_autoHeight: true, _width: 200, _layout_fitWidth: true, title: value });
const onLayoutDoc = this.onLayoutDoc(key);
- FormattedTextBox.SelectOnLoad = newDoc[Id];
+ FormattedTextBox.SetSelectOnLoad(newDoc);
FormattedTextBox.SelectOnLoadChar = value;
- (onLayoutDoc ? newDoc : newDoc[DocData])[key] = this.getValue(this.props.heading);
- const docs = this.props.parent.childDocList;
- return docs ? (docs.splice(0, 0, newDoc) ? true : false) : this.props.parent.props.addDocument?.(newDoc) || false; // should really extend addDocument to specify insertion point (at beginning of list)
+ (onLayoutDoc ? newDoc : newDoc[DocData])[key] = this.getValue(this._props.heading);
+ const docs = this._props.parent.childDocList;
+ return docs ? (docs.splice(0, 0, newDoc) ? true : false) : this._props.parent._props.addDocument?.(newDoc) || false; // should really extend addDocument to specify insertion point (at beginning of list)
};
deleteRow = undoBatch(
action(() => {
this._createEmbeddingSelected = false;
- const key = this.props.pivotField;
- this.props.docList.forEach(d => Doc.SetInPlace(d, key, undefined, true));
- if (this.props.parent.colHeaderData && this.props.headingObject) {
- const index = this.props.parent.colHeaderData.indexOf(this.props.headingObject);
- this.props.parent.colHeaderData.splice(index, 1);
+ const key = this._props.pivotField;
+ this._props.docList.forEach(d => Doc.SetInPlace(d, key, undefined, true));
+ if (this._props.parent.colHeaderData && this._props.headingObject) {
+ const index = this._props.parent.colHeaderData.indexOf(this._props.headingObject);
+ this._props.parent.colHeaderData.splice(index, 1);
}
})
);
@@ -182,8 +184,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
};
headerMove = (e: PointerEvent) => {
- const embedding = Doc.MakeEmbedding(this.props.Document);
- const key = this.props.pivotField;
+ const embedding = Doc.MakeEmbedding(this._props.Document);
+ const key = this._props.pivotField;
let value = this.getValue(this.heading);
value = typeof value === 'string' ? `"${value}"` : value;
const script = `return doc.${key} === ${value}`;
@@ -198,7 +200,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
@action
headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
if (e.button === 0 && !e.ctrlKey) {
- setupMoveUpEvents(this, e, this.headerMove, emptyFunction, e => !this.props.chromeHidden && this.collapseSection(e));
+ setupMoveUpEvents(this, e, this.headerMove, emptyFunction, e => !this._props.chromeHidden && this.collapseSection(e));
this._createEmbeddingSelected = false;
}
};
@@ -207,7 +209,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
* Returns true if a key is on the layout doc of the documents in the collection.
*/
onLayoutDoc = (key: string): boolean => {
- DocListCast(this.props.parent.Document.data).forEach(doc => {
+ DocListCast(this._props.parent.Document.data).forEach(doc => {
if (Doc.Get(doc, key, true)) return true;
});
return false;
@@ -246,37 +248,25 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
toggleEmbedding = action(() => (this._createEmbeddingSelected = true));
toggleVisibility = () => (this._collapsed = !this.collapsed);
- renderMenu = () => {
- const selected = this._createEmbeddingSelected;
- return (
- <div className="collectionStackingView-optionPicker">
- <div className="optionOptions">
- <div className={'optionPicker' + (selected === true ? ' active' : '')} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.deleteRow)}>
- Delete
- </div>
- </div>
- </div>
- );
- };
@action
textCallback = (char: string) => {
return this.addDocument('', false);
};
@computed get contentLayout() {
- const rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
- const showChrome = !this.props.chromeHidden;
- const stackPad = showChrome ? `0px ${this.props.parent.xMargin}px` : `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px 0px ${this.props.parent.xMargin}px `;
+ const rows = Math.max(1, Math.min(this._props.docList.length, Math.floor((this._props.parent._props.PanelWidth() - 2 * this._props.parent.xMargin) / (this._props.parent.columnWidth + this._props.parent.gridGap))));
+ const showChrome = !this._props.chromeHidden;
+ const stackPad = showChrome ? `0px ${this._props.parent.xMargin}px` : `${this._props.parent.yMargin}px ${this._props.parent.xMargin}px 0px ${this._props.parent.xMargin}px `;
return this.collapsed ? null : (
<div style={{ position: 'relative' }}>
- {this.props.showHandle && this.props.parent.props.isContentActive() ? this.props.parent.columnDragger : null}
+ {this._props.showHandle && this._props.parent._props.isContentActive() ? this._props.parent.columnDragger : null}
{showChrome ? (
<div
className="collectionStackingView-addDocumentButton"
style={
{
//width: style.columnWidth / style.numGroupColumns,
- //padding: `${NumCast(this.props.parent.layoutDoc._yPadding, this.props.parent.yMargin)}px 0px 0px 0px`,
+ //padding: `${NumCast(this._props.parent.layoutDoc._yPadding, this._props.parent.yMargin)}px 0px 0px 0px`,
}
}>
<EditableView GetValue={returnEmptyString} SetValue={this.addDocument} textCallback={this.textCallback} contents={'+ NEW'} />
@@ -287,25 +277,25 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
ref={this._contRef}
style={{
padding: stackPad,
- minHeight: this.props.showHandle && this.props.parent.props.isContentActive() ? '10px' : undefined,
- width: this.props.parent.NodeWidth,
- gridGap: this.props.parent.gridGap,
- gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ''),
+ minHeight: this._props.showHandle && this._props.parent._props.isContentActive() ? '10px' : undefined,
+ width: this._props.parent.NodeWidth,
+ gridGap: this._props.parent.gridGap,
+ gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this._props.parent.columnWidth}px`, ''),
}}>
- {this.props.parent.children(this.props.docList)}
+ {this._props.parent.children(this._props.docList)}
</div>
</div>
);
}
@computed get headingView() {
- const noChrome = this.props.chromeHidden;
- const key = this.props.pivotField;
- const evContents = this.heading ? this.heading : this.props.type && this.props.type === 'number' ? '0' : `NO ${key.toUpperCase()} VALUE`;
+ const noChrome = this._props.chromeHidden;
+ const key = this._props.pivotField;
+ const evContents = this.heading ? this.heading : this._props.type && this._props.type === 'number' ? '0' : `NO ${key.toUpperCase()} VALUE`;
const editableHeaderView = <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} />;
- return this.props.Document.miniHeaders ? (
+ return this._props.Document.miniHeaders ? (
<div className="collectionStackingView-miniHeader">{editableHeaderView}</div>
- ) : !this.props.headingObject ? null : (
+ ) : !this._props.headingObject ? null : (
<div className="collectionStackingView-sectionHeader" ref={this._headerRef}>
<div
className="collectionStackingView-sectionHeader-subCont"
@@ -338,11 +328,9 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
)}
{noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
<div className="collectionStackingView-sectionOptions" onPointerDown={e => e.stopPropagation()}>
- <Flyout anchorPoint={anchorPoints.RIGHT_TOP} content={this.renderMenu()}>
- <button className="collectionStackingView-sectionOptionButton">
- <FontAwesomeIcon icon="ellipsis-v" size="lg" />
- </button>
- </Flyout>
+ <button className="collectionStackingView-sectionOptionButton" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.deleteRow)}>
+ <FontAwesomeIcon icon="trash" size="lg" />
+ </button>
</div>
)}
</div>
@@ -352,7 +340,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
render() {
const background = this._background;
return (
- <div className="collectionStackingView-masonrySection" style={{ width: this.props.parent.NodeWidth, background }} ref={this.createRowDropRef} onPointerEnter={this.pointerEnteredRow} onPointerLeave={this.pointerLeaveRow}>
+ <div className="collectionStackingView-masonrySection" style={{ width: this._props.parent.NodeWidth, background }} ref={this.createRowDropRef} onPointerEnter={this.pointerEnteredRow} onPointerLeave={this.pointerLeaveRow}>
{this.headingView}
{this.contentLayout}
</div>