aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-08-03 09:24:34 -0400
committerbobzel <zzzman@gmail.com>2022-08-03 09:24:34 -0400
commitbb907c6c10c1515c555c0ad12bd2eebb17edfb73 (patch)
tree68fd2487091cf5f2b4da388bab00ac084d0f2ff2 /src
parentb8bef1149b057d59076fe2c5e46d4b42c1f2ecdd (diff)
from last
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx211
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx335
-rw-r--r--src/client/views/collections/CollectionView.tsx24
3 files changed, 308 insertions, 262 deletions
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ff7594e5a..d3a8af03a 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -43,62 +43,85 @@ export type collectionStackingViewProps = {
@observer
export class CollectionStackingView extends CollectionSubView<Partial<collectionStackingViewProps>>() {
_masonryGridRef: HTMLDivElement | null = null;
- // used in a column dragger, likely due for the masonry grid view. We want to use this
+ // used in a column dragger, likely due for the masonry grid view. We want to use this
_draggerRef = React.createRef<HTMLDivElement>();
// Not sure what a pivot field is. Seems like we cause reaction in MobX get rid of it once we exit this view
_pivotFieldDisposer?: IReactionDisposer;
// Seems like we cause reaction in MobX get rid of our height once we exit this view
_autoHeightDisposer?: IReactionDisposer;
// keeping track of documents. Updated on internal and external drops. What's the difference?
- _docXfs: { height: () => number, width: () => number, stackedDocTransform: () => Transform }[] = [];
+ _docXfs: { height: () => number; width: () => number; stackedDocTransform: () => Transform }[] = [];
// Doesn't look like this field is being used anywhere. Obsolete?
_columnStart: number = 0;
// map of node headers to their heights. Used in Masonry
@observable _heightMap = new Map<string, number>();
// Assuming that this is the current css cursor style
- @observable _cursor: CursorProperty = "grab";
+ @observable _cursor: CursorProperty = 'grab';
// gets reset whenever we scroll. Not sure what it is
@observable _scroll = 0; // used to force the document decoration to update when scrolling
// does this mean whether the browser is hidden? Or is chrome something else entirely?
- @computed get chromeHidden() { return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden); }
+ @computed get chromeHidden() {
+ return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
+ }
// it looks like this gets the column headers that Mehek was showing just now
- @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null); }
+ @computed get columnHeaders() {
+ return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null);
+ }
// Still not sure what a pivot is, but it appears that we can actually filter docs somehow?
- @computed get pivotField() { return StrCast(this.layoutDoc._pivotField); }
+ @computed get pivotField() {
+ return StrCast(this.layoutDoc._pivotField);
+ }
// filteredChildren is what you want to work with. It's the list of things that you're currently displaying
- @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); }
+ @computed get filteredChildren() {
+ return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout);
+ }
// how much margin we give the header
- @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); }
- @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
- @computed get yMargin() { return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); }
- @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); }
+ @computed get headerMargin() {
+ return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin);
+ }
+ @computed get xMargin() {
+ return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, 0.05 * this.props.PanelWidth()));
+ }
+ @computed get yMargin() {
+ return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5);
+ } // 2 * this.gridGap)); }
+ @computed get gridGap() {
+ return NumCast(this.layoutDoc._gridGap, 10);
+ }
// are we stacking or masonry?
- @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking); }
+ @computed get isStackingView() {
+ return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking);
+ }
// this is the number of StackingViewFieldColumns that we have
- @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
+ @computed get numGroupColumns() {
+ return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1;
+ }
// reveals a button to add a group in masonry view
- @computed get showAddAGroup() { return this.pivotField && !this.chromeHidden; }
+ @computed get showAddAGroup() {
+ return this.pivotField && !this.chromeHidden;
+ }
// columnWidth handles the margin on the left and right side of the documents
@computed get columnWidth() {
- return Math.min(this.props.PanelWidth() - 2 * this.xMargin,
- this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
+ return Math.min(this.props.PanelWidth() - 2 * this.xMargin, this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
+ }
+
+ @computed get NodeWidth() {
+ return this.props.PanelWidth() - this.gridGap;
}
-
- @computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; }
constructor(props: any) {
super(props);
if (this.columnHeaders === undefined) {
- // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out?
- // here we're making an empty list of column headers (again, what Mehek showed us)
+ // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out?
+ // here we're making an empty list of column headers (again, what Mehek showed us)
this.layoutDoc._columnHeaders = new List<SchemaHeaderField>();
}
}
// TODO: plj - these are the children
children = (docs: Doc[]) => {
- //TODO: can somebody explain me to what exactly TraceMobX is?
+ //TODO: can somebody explain me to what exactly TraceMobX is?
TraceMobx();
// appears that we are going to reset the _docXfs. TODO: what is Xfs?
this._docXfs.length = 0;
@@ -110,9 +133,11 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// just getting the style
const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
// So we're choosing whether we're going to render a column or a masonry doc
- return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} style={style} >
- {this.getDisplayDoc(d, width)}
- </div>;
+ return (
+ <div className={`collectionStackingView-${this.isStackingView ? 'columnDoc' : 'masonryDoc'}`} key={d[Id]} style={style}>
+ {this.getDisplayDoc(d, width)}
+ </div>
+ );
});
};
@action
@@ -288,49 +313,52 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const stackedDocTransform = () => this.getDocTransform(doc, dref);
this._docXfs.push({ stackedDocTransform, width, height });
//DocumentView is how the node will be rendered
- return <DocumentView ref={r => dref = r || undefined}
- Document={doc}
- DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
- renderDepth={this.props.renderDepth + 1}
- PanelWidth={width}
- PanelHeight={height}
- styleProvider={this.styleProvider}
- docViewPath={this.props.docViewPath}
- fitWidth={this.props.childFitWidth}
- isContentActive={this.isChildContentActive}
- onKey={this.onKeyDown}
- isDocumentActive={this.isContentActive}
- LayoutTemplate={this.props.childLayoutTemplate}
- LayoutTemplateString={this.props.childLayoutString}
- NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeWidth(doc) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
- NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeHeight(doc) ? height : undefined}
- dontCenter={this.props.childIgnoreNativeSize ? "xy" : undefined}
- dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't autoHeight resize if dontRegisterView is set, but they need to.
+ return (
+ <DocumentView
+ ref={r => (dref = r || undefined)}
+ Document={doc}
+ DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
+ renderDepth={this.props.renderDepth + 1}
+ PanelWidth={width}
+ PanelHeight={height}
+ styleProvider={this.styleProvider}
+ docViewPath={this.props.docViewPath}
+ fitWidth={this.props.childFitWidth}
+ isContentActive={this.isChildContentActive}
+ onKey={this.onKeyDown}
+ isDocumentActive={this.isContentActive}
+ LayoutTemplate={this.props.childLayoutTemplate}
+ LayoutTemplateString={this.props.childLayoutString}
+ NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || (doc._fitWidth && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
+ NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || (doc._fitWidth && !Doc.NativeHeight(doc)) ? height : undefined}
+ dontCenter={this.props.childIgnoreNativeSize ? 'xy' : undefined}
+ dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't autoHeight resize if dontRegisterView is set, but they need to.
rootSelected={this.rootSelected}
- showTitle={this.props.childShowTitle}
- dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
- onClick={this.onChildClickHandler}
- onDoubleClick={this.onChildDoubleClickHandler}
- ScreenToLocalTransform={stackedDocTransform}
- focus={this.focusDocument}
- docFilters={this.childDocFilters}
- hideDecorationTitle={this.props.childHideDecorationTitle?.()}
- hideResizeHandles={this.props.childHideResizeHandles?.()}
- hideTitle={this.props.childHideTitle?.()}
- docRangeFilters={this.childDocRangeFilters}
- searchFilterDocs={this.searchFilterDocs}
- ContainingCollectionDoc={this.props.CollectionView?.props.Document}
- ContainingCollectionView={this.props.CollectionView}
- addDocument={this.props.addDocument}
- moveDocument={this.props.moveDocument}
- removeDocument={this.props.removeDocument}
- contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
- whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
- addDocTab={this.addDocTab}
- bringToFront={returnFalse}
- scriptContext={this.props.scriptContext}
- pinToPres={this.props.pinToPres}
- />;
+ showTitle={this.props.childShowTitle}
+ dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
+ onClick={this.onChildClickHandler}
+ onDoubleClick={this.onChildDoubleClickHandler}
+ ScreenToLocalTransform={stackedDocTransform}
+ focus={this.focusDocument}
+ docFilters={this.childDocFilters}
+ hideDecorationTitle={this.props.childHideDecorationTitle?.()}
+ hideResizeHandles={this.props.childHideResizeHandles?.()}
+ hideTitle={this.props.childHideTitle?.()}
+ docRangeFilters={this.childDocRangeFilters}
+ searchFilterDocs={this.searchFilterDocs}
+ ContainingCollectionDoc={this.props.CollectionView?.props.Document}
+ ContainingCollectionView={this.props.CollectionView}
+ addDocument={this.props.addDocument}
+ moveDocument={this.props.moveDocument}
+ removeDocument={this.props.removeDocument}
+ contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
+ whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
+ addDocTab={this.addDocTab}
+ bringToFront={returnFalse}
+ scriptContext={this.props.scriptContext}
+ pinToPres={this.props.pinToPres}
+ />
+ );
}
getDocTransform(doc: Doc, dref?: DocumentView) {
@@ -345,10 +373,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// TODO: pj - replace with a better way to calculate the margin
let margin = 25;
d.margin = 25;
- if (this.columnWidth < 150){
- margin = 0;
+ if (this.columnWidth < 150) {
+ margin = 0;
}
- const maxWidth = (this.columnWidth / this.numGroupColumns) - (margin * 2);
+ const maxWidth = this.columnWidth / this.numGroupColumns - margin * 2;
if (!this.layoutDoc._columnsFill && !(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d))) {
return Math.min(d[WidthSym](), maxWidth);
}
@@ -399,37 +427,30 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// TODO: plj
@action
onPointerOver = (e: React.PointerEvent) => {
- // console.log("hovering over something")
- if (DragManager.docsBeingDragged.length) {
- // essentially copying code from onInternalDrop for this:
- const doc = DragManager.docsBeingDragged[0]
- // console.log(doc[LayoutSym]())
-
- console.log(doc[DataSym])
- console.log(Doc.IndexOf(doc, this.childDocs))
-
- }
-
-
- }
+ // console.log("hovering over something")
+ if (DragManager.docsBeingDragged.length) {
+ // essentially copying code from onInternalDrop for this:
+ const doc = DragManager.docsBeingDragged[0];
+ // console.log(doc[LayoutSym]())
+
+ console.log(doc[DataSym]);
+ console.log(Doc.IndexOf(doc, this.childDocs));
+ }
+ };
//used in onPointerOver to swap two nodes in the rendered filtered children list
- swapNodes = (i: number, j: number) => {
-
- }
+ swapNodes = (i: number, j: number) => {};
- //plj added this
+ //plj added this
@action
- onPointerDown = (e: React.PointerEvent) => {
-
- }
+ onPointerDown = (e: React.PointerEvent) => {};
- // TODO: plj - look at this. Start with making changes to db, and then transition to client side
+ // TODO: plj - look at this. Start with making changes to db, and then transition to client side
@undoBatch
@action
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
- // Fairly confident that this is where the swapping of nodes in the various arrays happens
- console.log('drop')
+ // Fairly confident that this is where the swapping of nodes in the various arrays happens
+ console.log('drop');
const where = [de.x, de.y];
// start at -1 until we're sure we want to add it to the column
let dropInd = -1;
@@ -450,7 +471,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
});
const oldDocs = this.childDocs.length;
if (super.onInternalDrop(e, de)) {
- // check to see if we actually need anything to the new column of nodes (if droppedDocs != empty)
+ // check to see if we actually need anything to the new column of nodes (if droppedDocs != empty)
const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments; // if nothing was added to the end of the list, then presumably the dropped documents were already in the list, but possibly got reordered so we use them.
@@ -489,7 +510,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
//What is the difference between internal and external drop?? Does internal mean we're dropping inside of a collection?
// I take it back: external drop means we took it out of column/collection that we were just in
onExternalDrop = async (e: React.DragEvent): Promise<void> => {
- console.log('external drop')
+ console.log('external drop');
const where = [e.clientX, e.clientY];
let targInd = -1;
this._docXfs.map((cd, i) => {
@@ -641,7 +662,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
}
};
- //
+ //
@computed get renderedSections() {
TraceMobx();
let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index d29c0b183..7b268cd49 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -1,28 +1,28 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, DocListCast, Opt } from "../../../fields/Doc";
-import { RichTextField } from "../../../fields/RichTextField";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { ScriptField } from "../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { ImageField } from "../../../fields/URLField";
-import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, setupMoveUpEvents, returnFalse, returnEmptyString } from "../../../Utils";
-import { Docs, DocUtils } from "../../documents/Documents";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { DragManager } from "../../util/DragManager";
-import { SnappingManager } from "../../util/SnappingManager";
-import { Transform } from "../../util/Transform";
-import { undoBatch } from "../../util/UndoManager";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { EditableView } from "../EditableView";
-import "./CollectionStackingView.scss";
-import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
-import { Id } from "../../../fields/FieldSymbols";
-const higflyout = require("@hig/flyout");
+import React = require('react');
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { RichTextField } from '../../../fields/RichTextField';
+import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
+import { emptyFunction, setupMoveUpEvents, returnFalse, returnEmptyString } from '../../../Utils';
+import { Docs, DocUtils } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DragManager } from '../../util/DragManager';
+import { SnappingManager } from '../../util/SnappingManager';
+import { Transform } from '../../util/Transform';
+import { undoBatch } from '../../util/UndoManager';
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
+import { EditableView } from '../EditableView';
+import './CollectionStackingView.scss';
+import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import { Id } from '../../../fields/FieldSymbols';
+const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -40,7 +40,7 @@ interface CSVFieldColumnProps {
columnWidth: number;
numGroupColumns: number;
gridGap: number;
- type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
+ type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined;
headings: () => object[];
// I think that stacking view actually has a single column and then supposedly you can add more columns? Unsure
renderChildren: (docs: Doc[]) => JSX.Element[];
@@ -53,14 +53,14 @@ interface CSVFieldColumnProps {
@observer
export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldColumnProps> {
- @observable private _background = "inherit";
+ @observable private _background = 'inherit';
private dropDisposer?: DragManager.DragDropDisposer;
private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
@observable _paletteOn = false;
@observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
- @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+ @observable _color = this.props.headingObject ? this.props.headingObject.color : '#f1efeb';
_ele: HTMLElement | null = null;
@@ -73,7 +73,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
this.props.observeHeight(ele);
this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
}
- }
+ };
componentWillUnmount() {
this.props.unobserveHeight(this._ele);
@@ -88,10 +88,10 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
getValue = (value: string): any => {
const parsed = parseInt(value);
if (!isNaN(parsed)) return parsed;
- if (value.toLowerCase().indexOf("true") > -1) return true;
- if (value.toLowerCase().indexOf("false") > -1) return false;
+ if (value.toLowerCase().indexOf('true') > -1) return true;
+ if (value.toLowerCase().indexOf('false') > -1) return false;
return value;
- }
+ };
@action
headingChanged = (value: string, shiftDown?: boolean) => {
@@ -100,7 +100,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
if (this.props.columnHeaders?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
return false;
}
- this.props.docList.forEach(d => d[this.props.pivotField] = castedValue);
+ this.props.docList.forEach(d => (d[this.props.pivotField] = castedValue));
if (this.props.headingObject) {
this.props.headingObject.setHeading(castedValue.toString());
this._heading = this.props.headingObject.heading;
@@ -108,17 +108,17 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
return true;
}
return false;
- }
+ };
@action
changeColumnColor = (color: string) => {
this.props.headingObject?.setColor(color);
this._color = color;
- }
+ };
- @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = "#b4b4b4");
- @action pointerLeave = () => this._background = "inherit";
- textCallback = (char: string) => this.addNewTextDoc("-typed text-", false, true);
+ @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4');
+ @action pointerLeave = () => (this._background = 'inherit');
+ textCallback = (char: string) => this.addNewTextDoc('-typed text-', false, true);
@action
addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
@@ -126,73 +126,78 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
const key = this.props.pivotField;
const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _fitWidth: true, title: value, _autoHeight: true });
newDoc[key] = this.getValue(this.props.heading);
- const maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
+ const maxHeading = this.props.docList.reduce((maxHeading, doc) => (NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading), 0);
const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
newDoc.heading = heading;
FormattedTextBox.SelectOnLoad = newDoc[Id];
- FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? "" : " ";
+ FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
return this.props.addDocument?.(newDoc) || false;
- }
+ };
@action
deleteColumn = () => {
- this.props.docList.forEach(d => d[this.props.pivotField] = undefined);
+ this.props.docList.forEach(d => (d[this.props.pivotField] = undefined));
if (this.props.columnHeaders && this.props.headingObject) {
const index = this.props.columnHeaders.indexOf(this.props.headingObject);
this.props.columnHeaders.splice(index, 1);
}
- }
+ };
@action
collapseSection = () => {
this.props.headingObject?.setCollapsed(!this.props.headingObject.collapsed);
this.toggleVisibility();
- }
+ };
headerDown = (e: React.PointerEvent<HTMLDivElement>) => setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
- //TODO: I think this is where I'm supposed to edit stuff
+ //TODO: I think this is where I'm supposed to edit stuff
startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
// is MakeAlias a way to make a copy of a doc without rendering it?
const alias = Doc.MakeAlias(this.props.Document);
alias._width = this.props.columnWidth / (this.props.columnHeaders?.length || 1);
alias._pivotField = undefined;
let value = this.getValue(this._heading);
- value = typeof value === "string" ? `"${value}"` : value;
+ value = typeof value === 'string' ? `"${value}"` : value;
alias.viewSpecScript = ScriptField.MakeFunction(`doc.${this.props.pivotField} === ${value}`, { doc: Doc.name });
if (alias.viewSpecScript) {
DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY);
return true;
}
return false;
- }
+ };
renderColorPicker = () => {
- const gray = "#f1efeb";
+ const gray = '#f1efeb';
const selected = this.props.headingObject ? this.props.headingObject.color : gray;
- const colors = ["pink2", "purple4", "bluegreen1", "yellow4", "gray", "red2", "bluegreen7", "bluegreen5", "orange1"];
- return <div className="collectionStackingView-colorPicker">
- <div className="colorOptions">
- {colors.map(col => {
- const palette = PastelSchemaPalette.get(col);
- return <div className={"colorPicker" + (selected === palette ? " active" : "")}
- style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
- })}
+ const colors = ['pink2', 'purple4', 'bluegreen1', 'yellow4', 'gray', 'red2', 'bluegreen7', 'bluegreen5', 'orange1'];
+ return (
+ <div className="collectionStackingView-colorPicker">
+ <div className="colorOptions">
+ {colors.map(col => {
+ const palette = PastelSchemaPalette.get(col);
+ return <div className={'colorPicker' + (selected === palette ? ' active' : '')} style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
+ })}
+ </div>
</div>
- </div>;
- }
+ );
+ };
renderMenu = () => {
- return <div className="collectionStackingView-optionPicker">
- <div className="optionOptions">
- <div className={"optionPicker" + (true ? " active" : "")} onClick={action(() => { })}>Add options here</div>
+ return (
+ <div className="collectionStackingView-optionPicker">
+ <div className="optionOptions">
+ <div className={'optionPicker' + (true ? ' active' : '')} onClick={action(() => {})}>
+ Add options here
+ </div>
+ </div>
</div>
- </div >;
- }
+ );
+ };
@observable private collapsed: boolean = false;
- private toggleVisibility = action(() => this.collapsed = !this.collapsed);
+ private toggleVisibility = action(() => (this.collapsed = !this.collapsed));
menuCallback = (x: number, y: number) => {
ContextMenu.Instance.clearItems();
@@ -200,42 +205,58 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
const docItems: ContextMenuProps[] = [];
const dataDoc = this.props.DataDoc || this.props.Document;
- DocUtils.addDocumentCreatorMenuItems((doc) => {
- FormattedTextBox.SelectOnLoad = doc[Id];
- return this.props.addDocument?.(doc);
- }, this.props.addDocument, x, y, true);
+ DocUtils.addDocumentCreatorMenuItems(
+ doc => {
+ FormattedTextBox.SelectOnLoad = doc[Id];
+ return this.props.addDocument?.(doc);
+ },
+ this.props.addDocument,
+ x,
+ y,
+ true
+ );
- Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey =>
- docItems.push({
- description: ":" + fieldKey, event: () => {
- const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
- if (created) {
- if (this.props.Document.isTemplateDoc) {
- Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+ Array.from(Object.keys(Doc.GetProto(dataDoc)))
+ .filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof dataDoc[fieldKey] === 'string')
+ .map(fieldKey =>
+ docItems.push({
+ description: ':' + fieldKey,
+ event: () => {
+ const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
+ if (created) {
+ if (this.props.Document.isTemplateDoc) {
+ Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+ }
+ return this.props.addDocument?.(created);
}
- return this.props.addDocument?.(created);
- }
- }, icon: "compress-arrows-alt"
- }));
- Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => DocListCast(dataDoc[fieldKey]).length).map(fieldKey =>
- docItems.push({
- description: ":" + fieldKey, event: () => {
- const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
- if (created) {
- const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
- if (container.isTemplateDoc) {
- Doc.MakeMetadataFieldTemplate(created, container);
- return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+ },
+ icon: 'compress-arrows-alt',
+ })
+ );
+ Array.from(Object.keys(Doc.GetProto(dataDoc)))
+ .filter(fieldKey => DocListCast(dataDoc[fieldKey]).length)
+ .map(fieldKey =>
+ docItems.push({
+ description: ':' + fieldKey,
+ event: () => {
+ const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
+ if (created) {
+ const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
+ if (container.isTemplateDoc) {
+ Doc.MakeMetadataFieldTemplate(created, container);
+ return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+ }
+ return this.props.addDocument?.(created) || false;
}
- return this.props.addDocument?.(created) || false;
- }
- }, icon: "compress-arrows-alt"
- }));
- !Doc.noviceMode && ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" });
- !Doc.noviceMode && ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" });
- ContextMenu.Instance.setDefaultItem("::", (name: string): void => {
- Doc.GetProto(this.props.Document)[name] = "";
- const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true });
+ },
+ icon: 'compress-arrows-alt',
+ })
+ );
+ !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' });
+ !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' });
+ ContextMenu.Instance.setDefaultItem('::', (name: string): void => {
+ Doc.GetProto(this.props.Document)[name] = '';
+ const created = Docs.Create.TextDocument('', { title: name, _width: 250, _autoHeight: true });
if (created) {
if (this.props.Document.isTemplateDoc) {
Doc.MakeMetadataFieldTemplate(created, this.props.Document);
@@ -245,9 +266,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
});
const pt = this.props.screenToLocalTransform().inverse().transformPoint(x, y);
ContextMenu.Instance.displayMenu(x, y, undefined, true);
- }
-
-
+ };
@computed get innards() {
TraceMobx();
@@ -256,39 +275,39 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
const heading = this._heading;
const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin;
const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
- const evContents = heading ? heading : this.props?.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
- const headingView = this.props.headingObject ?
- <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
+ const evContents = heading ? heading : this.props?.type === 'number' ? '0' : `NO ${key.toUpperCase()} VALUE`;
+ const headingView = this.props.headingObject ? (
+ <div
+ key={heading}
+ className="collectionStackingView-sectionHeader"
+ ref={this._headerRef}
style={{
marginTop: this.props.yMargin,
- width: (this.props.columnWidth) /
- ((uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1)) || 1)
+ width: this.props.columnWidth / (uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1) || 1),
}}>
- <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
+ <div className={'collectionStackingView-collapseBar' + (this.props.headingObject.collapsed === true ? ' active' : '')} onClick={this.collapseSection}></div>
{/* the default bucket (no key value) has a tooltip that describes what it is.
Further, it does not have a color and cannot be deleted. */}
- <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
- title={evContents === `NO ${key.toUpperCase()} VALUE` ?
- `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
- style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "inherit" }}>
- <EditableView
- GetValue={() => evContents}
- SetValue={this.headingChanged}
- contents={evContents}
- oneLine={true}
- toggle={this.toggleVisibility} />
- {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+ <div
+ className="collectionStackingView-sectionHeader-subCont"
+ onPointerDown={this.headerDown}
+ title={evContents === `NO ${key.toUpperCase()} VALUE` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
+ style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : 'inherit' }}>
+ <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} toggle={this.toggleVisibility} />
+ {evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
<div className="collectionStackingView-sectionColor">
- <button className="collectionStackingView-sectionColorButton" onClick={action(e => this._paletteOn = !this._paletteOn)}>
+ <button className="collectionStackingView-sectionColorButton" onClick={action(e => (this._paletteOn = !this._paletteOn))}>
<FontAwesomeIcon icon="palette" size="lg" />
</button>
- {this._paletteOn ? this.renderColorPicker() : (null)}
+ {this._paletteOn ? this.renderColorPicker() : null}
</div>
+ )}
+ {
+ <button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
+ <FontAwesomeIcon icon="trash" size="lg" />
+ </button>
}
- {<button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
- <FontAwesomeIcon icon="trash" size="lg" />
- </button>}
- {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+ {evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
<div className="collectionStackingView-sectionOptions">
<Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
<button className="collectionStackingView-sectionOptionButton">
@@ -296,70 +315,76 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
</button>
</Flyout>
</div>
- }
+ )}
</div>
- </div> : (null);
+ </div>
+ ) : null;
const templatecols = `${this.props.columnWidth / this.props.numGroupColumns}px `;
const type = this.props.Document.type;
- return <>
- {this.props.Document._columnsHideIfEmpty ? (null) : headingView}
- {
- this.collapsed ? (null) :
+ return (
+ <>
+ {this.props.Document._columnsHideIfEmpty ? null : headingView}
+ {this.collapsed ? null : (
<div>
- <div key={`${heading}-stack`} className={`collectionStackingView-masonrySingle`}
+ <div
+ key={`${heading}-stack`}
+ className={`collectionStackingView-masonrySingle`}
style={{
padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`,
- margin: "auto",
- width: "max-content", //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
+ margin: 'auto',
+ width: 'max-content', //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
height: 'max-content',
- position: "relative",
+ position: 'relative',
gridGap: this.props.gridGap,
gridTemplateColumns: templatecols,
- gridAutoRows: "0px"
+ gridAutoRows: '0px',
}}>
{this.props.renderChildren(this.props.docList)}
</div>
- {!this.props.chromeHidden && type !== DocumentType.PRES ?
- // TODO: this is the "new" button: see what you can work with here
- // change cursor to pointer for this, and update dragging cursor
- //TODO: there is a bug that occurs when adding a freeform document and trying to move it around
- //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
- // bottom note
- //TODO: ok, so we are using a single column, and this is it!
- <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
- style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10, marginLeft: 25 }}>
+ {!this.props.chromeHidden && type !== DocumentType.PRES ? (
+ // TODO: this is the "new" button: see what you can work with here
+ // change cursor to pointer for this, and update dragging cursor
+ //TODO: there is a bug that occurs when adding a freeform document and trying to move it around
+ //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
+ // bottom note
+ //TODO: ok, so we are using a single column, and this is it!
+ <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton" style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10, marginLeft: 25 }}>
<EditableView
GetValue={returnEmptyString}
SetValue={this.addNewTextDoc}
textCallback={this.textCallback}
placeholder={"Type ':' for commands"}
- contents={<FontAwesomeIcon icon={"plus"}/>}
+ contents={<FontAwesomeIcon icon={'plus'} />}
toggle={this.toggleVisibility}
- menuCallback={this.menuCallback} />
+ menuCallback={this.menuCallback}
+ />
</div>
- : null
- }
+ ) : null}
</div>
- }
- </>;
+ )}
+ </>
+ );
}
-
render() {
TraceMobx();
const headings = this.props.headings();
const heading = this._heading;
const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
return (
- <div className={"collectionStackingViewFieldColumn" + (SnappingManager.GetIsDragging() ? "Dragging" : "")} key={heading}
+ <div
+ className={'collectionStackingViewFieldColumn' + (SnappingManager.GetIsDragging() ? 'Dragging' : '')}
+ key={heading}
style={{
width: `${100 / (uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1) || 1)}%`,
height: undefined, // DraggingManager.GetIsDragging() ? "100%" : undefined,
- background: this._background
+ background: this._background,
}}
- ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
+ ref={this.createColumnDropRef}
+ onPointerEnter={this.pointerEntered}
+ onPointerLeave={this.pointerLeave}>
{this.innards}
- </div >
+ </div>
);
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 4ea675d35..1ee77d4ce 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -140,18 +140,18 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
if (addExtras && CollectionView._safeMode) {
ContextMenu.Instance.addItem({ description: 'Test Freeform', event: () => func(CollectionViewType.Invalid), icon: 'project-diagram' });
}
- subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" });
- subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" });
- subItems.push({ description: "Stacking", event: () => func(CollectionViewType.Stacking)._autoHeight = true, icon: "ellipsis-v" });
- subItems.push({ description: "Notetaking", event: () => func(CollectionViewType.NoteTaking)._autoHeight = true, icon: "ellipsis-v" });
- subItems.push({ description: "Multicolumn", event: () => func(CollectionViewType.Multicolumn), icon: "columns" });
- subItems.push({ description: "Multirow", event: () => func(CollectionViewType.Multirow), icon: "columns" });
- subItems.push({ description: "Masonry", event: () => func(CollectionViewType.Masonry), icon: "columns" });
- subItems.push({ description: "Carousel", event: () => func(CollectionViewType.Carousel), icon: "columns" });
- subItems.push({ description: "3D Carousel", event: () => func(CollectionViewType.Carousel3D), icon: "columns" });
- !Doc.noviceMode && subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" });
- !Doc.noviceMode && subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" });
- subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "th-list" });
+ subItems.push({ description: 'Schema', event: () => func(CollectionViewType.Schema), icon: 'th-list' });
+ subItems.push({ description: 'Tree', event: () => func(CollectionViewType.Tree), icon: 'tree' });
+ subItems.push({ description: 'Stacking', event: () => (func(CollectionViewType.Stacking)._autoHeight = true), icon: 'ellipsis-v' });
+ subItems.push({ description: 'Notetaking', event: () => (func(CollectionViewType.NoteTaking)._autoHeight = true), icon: 'ellipsis-v' });
+ subItems.push({ description: 'Multicolumn', event: () => func(CollectionViewType.Multicolumn), icon: 'columns' });
+ subItems.push({ description: 'Multirow', event: () => func(CollectionViewType.Multirow), icon: 'columns' });
+ subItems.push({ description: 'Masonry', event: () => func(CollectionViewType.Masonry), icon: 'columns' });
+ subItems.push({ description: 'Carousel', event: () => func(CollectionViewType.Carousel), icon: 'columns' });
+ subItems.push({ description: '3D Carousel', event: () => func(CollectionViewType.Carousel3D), icon: 'columns' });
+ !Doc.noviceMode && subItems.push({ description: 'Pivot/Time', event: () => func(CollectionViewType.Time), icon: 'columns' });
+ !Doc.noviceMode && subItems.push({ description: 'Map', event: () => func(CollectionViewType.Map), icon: 'globe-americas' });
+ subItems.push({ description: 'Grid', event: () => func(CollectionViewType.Grid), icon: 'th-list' });
if (!Doc.IsSystem(this.rootDoc) && !this.rootDoc.isGroup && !this.rootDoc.annotationOn) {
const existingVm = ContextMenu.Instance.findByDescription(category);