aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionNoteTakingView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionNoteTakingView.tsx')
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx145
1 files changed, 61 insertions, 84 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index b359ef420..b0f64ed60 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -3,7 +3,7 @@ import { CursorProperty } from 'csstype';
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { DataSym, Doc, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
-import { Id } from '../../../fields/FieldSymbols';
+import { Copy, Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
@@ -11,7 +11,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Ty
import { TraceMobx } from '../../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, returnZero, smoothScroll, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
-import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { DocumentType } from '../../documents/DocumentTypes';
import { DragManager, dropActionType } from '../../util/DragManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
@@ -19,7 +19,6 @@ import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { LightboxView } from '../LightboxView';
-import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
@@ -30,13 +29,6 @@ import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivid
import { CollectionSubView } from './CollectionSubView';
const _global = (window /* browser */ || global) /* node */ as any;
-export type collectionNoteTakingViewProps = {
- chromeHidden?: boolean;
- viewType?: CollectionViewType;
- NativeWidth?: () => number;
- NativeHeight?: () => number;
-};
-
/**
* CollectionNoteTakingView is a column-based view for displaying documents. In this view, the user can (1)
* add and remove columns (2) change column sizes and (3) move documents within and between columns. This
@@ -45,41 +37,42 @@ export type collectionNoteTakingViewProps = {
* the rest of Dash, so it may be worthwhile to transition the headers to simple documents.
*/
@observer
-export class CollectionNoteTakingView extends CollectionSubView<Partial<collectionNoteTakingViewProps>>() {
+export class CollectionNoteTakingView extends CollectionSubView() {
_disposers: { [key: string]: IReactionDisposer } = {};
_masonryGridRef: HTMLDivElement | null = null;
_draggerRef = React.createRef<HTMLDivElement>();
+ notetakingCategoryField = 'NotetakingCategory';
+ public DividerWidth = 16;
@observable docsDraggedRowCol: number[] = [];
@observable _cursor: CursorProperty = 'grab';
@observable _scroll = 0;
@computed get chromeHidden() {
- return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
+ return BoolCast(this.layoutDoc.chromeHidden);
}
// columnHeaders returns the list of SchemaHeaderFields currently being used by the layout doc to render the columns
@computed get columnHeaders() {
const columnHeaders = Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null);
- const needsUnsetCategory = this.childDocs.some(d => !d[this.notetakingCategoryField] && !columnHeaders.find(sh => sh.heading === 'unset'));
- if (needsUnsetCategory) {
- setTimeout(() => columnHeaders.push(new SchemaHeaderField('unset', undefined, undefined, 1)));
+ const needsUnsetCategory = this.childDocs.some(d => !d[this.notetakingCategoryField] && !columnHeaders?.find(sh => sh.heading === 'unset'));
+ if (needsUnsetCategory || columnHeaders === undefined || columnHeaders.length === 0) {
+ setTimeout(() => {
+ const columnHeaders = Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null);
+ const needsUnsetCategory = this.childDocs.some(d => !d[this.notetakingCategoryField] && !columnHeaders?.find(sh => sh.heading === 'unset'));
+ if (needsUnsetCategory || columnHeaders === undefined || columnHeaders.length === 0) {
+ if (columnHeaders) columnHeaders.push(new SchemaHeaderField('unset', undefined, undefined, 1));
+ else this.dataDoc.columnHeaders = new List<SchemaHeaderField>();
+ }
+ });
}
- return columnHeaders;
- }
- // notetakingCategoryField returns the key to accessing a document's column value
- @computed get notetakingCategoryField() {
- return 'NotetakingCategory';
+ return columnHeaders ?? ([] as SchemaHeaderField[]);
}
@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()));
- }
- // dividerWidth returns the width of a CollectionNoteTakingViewDivider
- @computed get dividerWidth() {
- return 32;
+ return NumCast(this.layoutDoc._xMargin, 5);
}
@computed get yMargin() {
- return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5);
+ return NumCast(this.layoutDoc._yMargin, 5);
}
@computed get gridGap() {
return NumCast(this.layoutDoc._gridGap, 10);
@@ -94,22 +87,13 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
}
// maxColWidth returns the maximum column width, which is slightly less than the total available space.
@computed get maxColWidth() {
- return this.props.PanelWidth() - 2 * this.xMargin;
+ return this.props.PanelWidth();
}
// availableWidth is the total amount of non-divider width. Since widths are stored relatively,
// we use availableWidth to convert from a percentage to a pixel count.
@computed get availableWidth() {
- const numDividers = this.columnHeaders.length - 1;
- return this.maxColWidth - numDividers * this.dividerWidth;
- }
-
- // Documents should NOT have column category fields until entering this view, so the contructor creates the 'New Column'
- // category for the user to then edit later.
- constructor(props: any) {
- super(props);
- if (this.columnHeaders === undefined) {
- this.dataDoc.columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column', undefined, undefined, 1)]);
- }
+ const numDividers = this.numGroupColumns - 1;
+ return this.maxColWidth - numDividers * this.DividerWidth;
}
// children is passed as a prop to the NoteTakingField, which uses this function
@@ -149,7 +133,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
}
});
// now we add back in the docs that we're dragging
- if (rowCol.length) {
+ if (rowCol.length && columnHeaders.length > rowCol[1]) {
const offset = 0;
sections.get(columnHeaders[rowCol[1]])?.splice(rowCol[0] - offset, 0, ...DragManager.docsBeingDragged);
}
@@ -209,7 +193,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
};
// let's dive in and get the actual document we want to drag/move around
- focusDocument = (doc: Doc, options?: DocFocusOptions) => {
+ focusDocument = (doc: Doc, options: DocFocusOptions) => {
Doc.BrushDoc(doc);
let focusSpeed = 0;
const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
@@ -217,7 +201,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
const top = found.getBoundingClientRect().top;
const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top);
if (Math.floor(localTop[1]) !== 0) {
- smoothScroll((focusSpeed = doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500), this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
+ smoothScroll((focusSpeed = NumCast(doc.focusSpeed, 500)), this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
}
}
const endFocus = async (moved: boolean) => (options?.afterFocus ? options?.afterFocus(moved) : ViewAdjustment.doNothing);
@@ -236,9 +220,6 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (this.props.childOpacity) {
return this.props.childOpacity();
}
- if (this.Document._currentFrame !== undefined) {
- return CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity;
- }
}
return this.props.styleProvider?.(doc, props, property);
};
@@ -315,12 +296,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as Field);
const existingHeader = this.columnHeaders.find(sh => sh.heading === heading);
const existingWidth = existingHeader?.width ? existingHeader.width : 0;
- const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth - 2 * this.xMargin : this.maxColWidth - 2 * this.xMargin;
- if (d.type === DocumentType.RTF) {
- return maxWidth;
- }
- const width = d[WidthSym]();
- return width < maxWidth ? width : maxWidth;
+ const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth;
+ const width = d.fitWidth ? maxWidth : d[WidthSym]();
+ return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth);
}
// how to get the height of a document. Nothing special here.
@@ -332,8 +310,6 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[WidthSym]() : 0);
const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[HeightSym]() : 0);
if (nw && nh) {
- // const colWid = this.columnWidth / this.numGroupColumns;
- // const docWid = this.layoutDoc._columnsFill ? colWid : Math.min(this.getDocWidth(d), colWid);
const docWid = this.getDocWidth(d);
return Math.min(maxHeight, (docWid * nh) / nw);
}
@@ -392,26 +368,27 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
});
// we alter the pivot fields of the docs in case they are moved to a new column.
const colIndex = this.getColumnFromXCoord(xCoord);
- const colHeader = StrCast(this.columnHeaders[colIndex].heading);
+ const colHeader = colIndex === undefined ? 'unset' : StrCast(this.columnHeaders[colIndex].heading);
DragManager.docsBeingDragged.forEach(d => (d[this.notetakingCategoryField] = colHeader));
// used to notify sections to re-render
this.docsDraggedRowCol.length = 0;
- this.docsDraggedRowCol.push(dropInd, this.getColumnFromXCoord(xCoord));
+ const columnFromCoord = this.getColumnFromXCoord(xCoord);
+ columnFromCoord !== undefined && this.docsDraggedRowCol.push(dropInd, columnFromCoord);
}
};
// getColumnFromXCoord returns the column index for a given x-coordinate (currently always the client's mouse coordinate).
// This function is used to know which document a column SHOULD be in while it is being dragged.
- getColumnFromXCoord = (xCoord: number): number => {
+ getColumnFromXCoord = (xCoord: number): number | undefined => {
+ let colIndex: number | undefined = undefined;
const numColumns = this.columnHeaders.length;
const coords = [];
let colStartXCoord = 0;
for (let i = 0; i < numColumns; i++) {
coords.push(colStartXCoord);
- colStartXCoord += this.columnHeaders[i].width * this.availableWidth + this.dividerWidth;
+ colStartXCoord += this.columnHeaders[i].width * this.availableWidth + this.DividerWidth;
}
coords.push(this.PanelWidth);
- let colIndex = 0;
for (let i = 0; i < numColumns; i++) {
if (xCoord > coords[i] && xCoord < coords[i + 1]) {
colIndex = i;
@@ -423,20 +400,16 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
// getDocsFromXCoord returns the docs of a column based on the x-coordinate provided.
getDocsFromXCoord = (xCoord: number): Doc[] => {
- const colIndex = this.getColumnFromXCoord(xCoord);
- const colHeader = StrCast(this.columnHeaders[colIndex].heading);
- // const docs = this.childDocList
- const docs = this.childDocs;
const docsMatchingHeader: Doc[] = [];
- if (docs) {
- docs.map(d => {
- if (d instanceof Promise) return;
- const sectionValue = (d[this.notetakingCategoryField] as object) ?? 'unset';
- if (sectionValue.toString() == colHeader) {
- docsMatchingHeader.push(d);
- }
- });
- }
+ const colIndex = this.getColumnFromXCoord(xCoord);
+ const colHeader = colIndex === undefined ? 'unset' : StrCast(this.columnHeaders[colIndex].heading);
+ this.childDocs?.map(d => {
+ if (d instanceof Promise) return;
+ const sectionValue = (d[this.notetakingCategoryField] as object) ?? 'unset';
+ if (sectionValue.toString() == colHeader) {
+ docsMatchingHeader.push(d);
+ }
+ });
return docsMatchingHeader;
};
@@ -511,7 +484,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
this.onPointerMove(true, e.clientX, e.clientY);
docus?.map((doc: Doc) => this.addDocument(doc));
const newDoc = this.childDocs.lastElement();
- const colHeader = StrCast(this.columnHeaders[colInd].heading);
+ const colHeader = colInd === undefined ? 'unset' : StrCast(this.columnHeaders[colInd].heading);
newDoc[this.notetakingCategoryField] = colHeader;
const docs = this.childDocList;
if (docs && targInd !== -1) {
@@ -566,13 +539,13 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
numGroupColumns={this.numGroupColumns}
gridGap={this.gridGap}
pivotField={this.notetakingCategoryField}
- dividerWidth={this.dividerWidth}
+ dividerWidth={this.DividerWidth}
maxColWidth={this.maxColWidth}
availableWidth={this.availableWidth}
PanelWidth={this.PanelWidth}
- key={heading?.heading ?? ''}
+ key={heading?.heading ?? 'unset'}
headings={this.headings}
- heading={heading?.heading ?? ''}
+ heading={heading?.heading ?? 'unset'}
headingObject={heading}
docList={docList}
yMargin={this.yMargin}
@@ -589,15 +562,19 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
@undoBatch
@action
addGroup = (value: string) => {
- for (const header of this.columnHeaders) {
- if (header.heading == value) {
- alert('You cannot use an existing column name. Please try a new column name');
- return value;
+ if (this.columnHeaders) {
+ for (const header of this.columnHeaders) {
+ if (header.heading == value) {
+ alert('You cannot use an existing column name. Please try a new column name');
+ return value;
+ }
}
}
const columnHeaders = Cast(this.props.Document.columnHeaders, listSpec(SchemaHeaderField), null);
const newColWidth = 1 / (this.numGroupColumns + 1);
- return value && columnHeaders?.push(new SchemaHeaderField(value, undefined, undefined, newColWidth)) && this.resizeColumns(true, newColWidth, this.columnHeaders.length - 1) ? true : false;
+ value && columnHeaders?.push(new SchemaHeaderField(value, undefined, undefined, newColWidth)) && this.resizeColumns(true, newColWidth, this.columnHeaders.length - 1);
+ this.dataDoc.columnHeaders = new List<SchemaHeaderField>(columnHeaders.map(header => header[Copy]()));
+ return true;
};
onContextMenu = (e: React.MouseEvent): void => {
@@ -642,10 +619,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
@computed get buttonMenu() {
const menuDoc: Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
if (menuDoc) {
- const width: number = NumCast(menuDoc._width, 30);
- const height: number = NumCast(menuDoc._height, 30);
+ const width = NumCast(menuDoc._width, 30);
+ const height = NumCast(menuDoc._height, 30);
return (
- <div className="buttonMenu-docBtn" style={{ width: width, height: height }}>
+ <div className="buttonMenu-docBtn" style={{ width, height }}>
<DocumentView
Document={menuDoc}
DataDoc={menuDoc}
@@ -678,10 +655,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
}
@computed get nativeWidth() {
- return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc);
+ return Doc.NativeWidth(this.layoutDoc);
}
@computed get nativeHeight() {
- return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc);
+ return Doc.NativeHeight(this.layoutDoc);
}
@computed get scaling() {