aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts9
-rw-r--r--src/client/util/CurrentUserUtils.ts3
-rw-r--r--src/client/util/DragManager.ts12
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/client/views/StyleProvider.tsx8
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx91
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx358
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewDivider.tsx112
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx30
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx6
11 files changed, 332 insertions, 303 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 32d7152fd..9d00664ad 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1036,7 +1036,14 @@ export namespace Docs {
}
export function NoteTakingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) {
- return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.NoteTaking }, id, undefined, protoId);
+ return InstanceFromProto(
+ Prototypes.get(DocumentType.COL),
+ new List(documents),
+ { columnHeaders: new List<SchemaHeaderField>([new SchemaHeaderField('Untitled')]), ...options, _viewType: CollectionViewType.NoteTaking },
+ id,
+ undefined,
+ protoId
+ );
}
export function MulticolumnDocument(documents: Array<Doc>, options: DocumentOptions) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 28dc44c25..7856c913b 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -135,7 +135,6 @@ export class CurrentUserUtils {
return DocUtils.AssignOpts(tempClicks, reqdOpts, reqdClickList) ?? (doc[field] = Docs.Create.TreeDocument(reqdClickList, reqdOpts));
}
-
/// Initializes templates that can be applied to notes
static setupNoteTemplates(doc: Doc, field="template-notes") {
const tempNotes = DocCast(doc[field]);
@@ -255,6 +254,7 @@ export class CurrentUserUtils {
creator:(opts:DocumentOptions)=> any // how to create the empty thing if it doesn't exist
}[] = [
{key: "Note", creator: opts => Docs.Create.TextDocument("", opts), opts: { _width: 200, _autoHeight: true }},
+ {key: "Noteboard", creator: opts => Docs.Create.NoteTakingDocument([], opts), opts: { _width: 250, _height: 200 }},
{key: "Collection", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 150, _height: 100 }},
{key: "Equation", creator: opts => Docs.Create.EquationDocument(opts), opts: { _width: 300, _height: 35, _fitWidth:false, _backgroundGridShow: true, }},
{key: "Webpage", creator: opts => Docs.Create.WebDocument("",opts), opts: { _width: 400, _height: 512, _nativeWidth: 850, useCors: true, }},
@@ -280,6 +280,7 @@ export class CurrentUserUtils {
return [
{ toolTip: "Tap or drag to create a note", title: "Note", icon: "sticky-note", dragFactory: doc.emptyNote as Doc, },
+ { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "folder", dragFactory: doc.emptyNoteboard as Doc, },
{ toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab), scripts: { onClick: 'openOnRight(copyDragFactory(this.clickFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
{ toolTip: "Tap or drag to create an equation", title: "Math", icon: "calculator", dragFactory: doc.emptyEquation as Doc, },
{ toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, },
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 3a1bb1673..f4987cf34 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,4 +1,4 @@
-import { action } from 'mobx';
+import { action, observable, runInAction } from 'mobx';
import { DateField } from '../../fields/DateField';
import { Doc, Field, Opt } from '../../fields/Doc';
import { List } from '../../fields/List';
@@ -320,7 +320,7 @@ export namespace DragManager {
y: snapVal([yFromTop, yFromBottom], e.pageY, SnappingManager.horizSnapLines()),
};
}
- export let docsBeingDragged: Doc[] = [];
+ export let docsBeingDragged: Doc[] = observable([] as Doc[]);
export let CanEmbed = false;
export let DocDragData: DocumentDragData | undefined;
export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
@@ -349,13 +349,13 @@ export namespace DragManager {
xs: number[] = [],
ys: number[] = [];
- docsBeingDragged = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnchorAnnoDragData ? [dragData.dragDocument] : [];
const elesCont = {
left: Number.MAX_SAFE_INTEGER,
right: Number.MIN_SAFE_INTEGER,
top: Number.MAX_SAFE_INTEGER,
bottom: Number.MIN_SAFE_INTEGER,
};
+ const docsToDrag = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnchorAnnoDragData ? [dragData.dragDocument] : [];
const dragElements = eles.map(ele => {
if (!ele.parentNode) dragDiv.appendChild(ele);
const dragElement = ele.parentNode === dragDiv ? ele : (ele.cloneNode(true) as HTMLElement);
@@ -405,7 +405,7 @@ export namespace DragManager {
});
dragLabel.style.transform = `translate(${rect.left + (options?.offsetX || 0)}px, ${rect.top + (options?.offsetY || 0) - 20}px)`;
- if (docsBeingDragged.length) {
+ if (docsToDrag.length) {
const pdfBox = dragElement.getElementsByTagName('canvas');
const pdfBoxSrc = ele.getElementsByTagName('canvas');
Array.from(pdfBox)
@@ -429,6 +429,8 @@ export namespace DragManager {
return dragElement;
});
+ runInAction(() => docsBeingDragged.push(...docsToDrag));
+
const hideDragShowOriginalElements = (hide: boolean) => {
dragLabel.style.display = hide ? '' : 'none';
!hide && dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
@@ -456,7 +458,7 @@ export namespace DragManager {
SnappingManager.SetIsDragging(false);
SnappingManager.clearSnapLines();
batch.end();
- docsBeingDragged = [];
+ docsBeingDragged.length = 0;
});
var startWindowDragTimer: any;
const moveHandler = (e: PointerEvent) => {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c53e61699..0db9eab69 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -351,7 +351,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
@action
onPointerDown = (e: React.PointerEvent): void => {
- DragManager.docsBeingDragged = SelectionManager.Views().map(dv => dv.rootDoc);
+ DragManager.docsBeingDragged.push(...SelectionManager.Views().map(dv => dv.rootDoc));
this._inkDragDocs = DragManager.docsBeingDragged
.filter(doc => doc.type === DocumentType.INK)
.map(doc => {
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 692f7b98e..a83163eb0 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -110,8 +110,8 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
return undefined;
case StyleProp.WidgetColor:
return isAnnotated ? Colors.LIGHT_BLUE : darkScheme() ? 'lightgrey' : 'dimgrey';
- // return doc = dragManager.dragDocument ? props.dragEffects.opacity??CastofOpacityonline94 : Cast())
- // same idea for background Color
+ // return doc = dragManager.dragDocument ? props.dragEffects.opacity??CastofOpacityonline94 : Cast())
+ // same idea for background Color
case StyleProp.Opacity:
return Cast(doc?._opacity, 'number', Cast(doc?.opacity, 'number', null));
case StyleProp.HideLinkButton:
@@ -156,7 +156,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case StyleProp.JitterRotation:
return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0;
case StyleProp.HeaderMargin:
- return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) || (doc?.type === DocumentType.RTF && !showTitle()?.includes('noMargin')) || doc?.type === DocumentType.LABEL) &&
+ return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
+ (doc?.type === DocumentType.RTF && !showTitle()?.includes('noMargin')) ||
+ doc?.type === DocumentType.LABEL) &&
showTitle() &&
!StrCast(doc?.showTitle).includes(':hover')
? 15
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index f442559fb..1854a4213 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,6 +1,6 @@
import React = require('react');
import { CursorProperty } from 'csstype';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { DataSym, Doc, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
@@ -21,10 +21,12 @@ 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';
import { StyleProp } from '../StyleProvider';
import './CollectionNoteTakingView.scss';
import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
-import CollectionNoteTakingViewDivider from './CollectionNoteTakingViewDivider';
+import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
import { CollectionSubView } from './CollectionSubView';
const _global = (window /* browser */ || global) /* node */ as any;
@@ -40,7 +42,6 @@ export type collectionNoteTakingViewProps = {
@observer
export class CollectionNoteTakingView extends CollectionSubView<Partial<collectionNoteTakingViewProps>>() {
- _pivotFieldDisposer?: IReactionDisposer;
_autoHeightDisposer?: IReactionDisposer;
_masonryGridRef: HTMLDivElement | null = null;
_draggerRef = React.createRef<HTMLDivElement>();
@@ -54,10 +55,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
}
@computed get columnHeaders() {
- return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null);
+ return Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null);
}
- @computed get pivotField() {
- return 'Col';
+ @computed get notetakingCategoryField() {
+ return 'noteTakingCategory';
}
@computed get filteredChildren() {
return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout);
@@ -90,7 +91,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
constructor(props: any) {
super(props);
if (this.columnHeaders === undefined) {
- this.layoutDoc._columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
+ this.dataDoc.columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
this.columnStartXCoords = [0];
// add all of the docs that have not been added to a column to this new column
} else {
@@ -126,18 +127,16 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
// filter out the currently dragged docs from the child docs, since we will insert them later
if (rowCol.length && DragManager.docsBeingDragged.length) {
const docIdsToRemove = new Set();
- DragManager.docsBeingDragged.forEach(d => {
- docIdsToRemove.add(d[Id]);
- });
+ DragManager.docsBeingDragged.forEach(d => docIdsToRemove.add(d[Id]));
docs = docs.filter(d => !docIdsToRemove.has(d[Id]));
}
// this will sort the docs into the correct columns (minus the ones you're currently dragging)
docs.map(d => {
- if (!d[this.pivotField]) {
- d[this.pivotField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
+ if (!d[this.notetakingCategoryField]) {
+ d[this.notetakingCategoryField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
}
- const sectionValue = d[this.pivotField] as object;
+ const sectionValue = d[this.notetakingCategoryField] as object;
// look for if header exists already
const existingHeader = columnHeaders.find(sh => sh.heading === sectionValue.toString());
@@ -156,14 +155,15 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
return sections;
}
+ removeDocDragHighlight = () => {
+ setTimeout(
+ action(() => (this.docsDraggedRowCol.length = 0)),
+ 100
+ );
+ };
componentDidMount() {
super.componentDidMount?.();
- // reset section headers when a new filter is inputted
- this._pivotFieldDisposer = reaction(
- () => this.pivotField,
- () => (this.layoutDoc._columnHeaders = new List())
- );
-
+ document.addEventListener('pointerup', this.removeDocDragHighlight, true);
this._autoHeightDisposer = reaction(
() => this.layoutDoc._autoHeight,
autoHeight => autoHeight && this.props.setHeight?.(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), this.headerMargin + Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace('px', ''))))))
@@ -171,8 +171,8 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
}
componentWillUnmount() {
+ document.removeEventListener('pointerup', this.removeDocDragHighlight, true);
super.componentWillUnmount();
- this._pivotFieldDisposer?.();
this._autoHeightDisposer?.();
}
@@ -227,6 +227,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
};
styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
+ if (property === StyleProp.BoxShadow && doc && DragManager.docsBeingDragged.includes(doc)) {
+ return `#9c9396 ${StrCast(doc?.boxShadow, '10px 10px 0.9vw')}`;
+ }
if (property === StyleProp.Opacity && doc) {
if (this.props.childOpacity) {
return this.props.childOpacity();
@@ -258,9 +261,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
docViewPath={this.props.docViewPath}
fitWidth={this.props.childFitWidth}
isContentActive={emptyFunction}
- originalBackgroundColor={StrCast(doc.backgroundColor)}
+ onKey={this.onKeyDown}
//TODO: change this from a prop to a parameter passed into a function
- isNoteTakingView={true}
+ dontHideOnDrag={true}
isDocumentActive={this.isContentActive}
LayoutTemplate={this.props.childLayoutTemplate}
LayoutTemplateString={this.props.childLayoutString}
@@ -307,7 +310,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
// how to get the width of a document. Currently returns the width of the column (minus margins)
// if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
getDocWidth(d: Doc) {
- const heading = d[this.pivotField] as object;
+ const heading = d[this.notetakingCategoryField] as object;
const castedSectionValue = heading.toString();
const existingHeader = this.columnHeaders.find(sh => sh.heading === castedSectionValue);
const colStartXCoords = this.columnStartXCoords;
@@ -364,20 +367,14 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (DragManager.docsBeingDragged.length && this.childDocList) {
// get the current docs for the column based on the mouse's x coordinate
// will use again later, which is why we're saving as local
- const xCoord = e.clientX - 2 * this.gridGap;
+ const xCoord = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0] - 2 * this.gridGap;
const colDocs = this.getDocsFromXCoord(xCoord);
// get the index for where you need to insert the doc you are currently dragging
- const clientY = e.clientY;
+ const clientY = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[1];
let dropInd = -1;
- // unsure whether we still want this dropAfter field
- // let dropAfter = 0;
- // manually set to 140, because not sure how to get exact value
- let pos0 = 140;
+ let pos0 = (this.refList.lastElement() as HTMLDivElement).children[0].getBoundingClientRect().height + this.yMargin * 2;
colDocs.forEach((doc, i) => {
- const noteTakingDocTransform = () => this.getDocTransform(doc);
- let pos1 = noteTakingDocTransform()
- .inverse()
- .transformPoint(0, this.getDocHeight(doc) + 2 * this.gridGap)[1];
+ let pos1 = this.getDocHeight(doc) + 2 * this.gridGap;
pos1 += pos0;
// updating drop position based on y coordinates
const yCoordInBetween = clientY > pos0 && (clientY < pos1 || i == colDocs.length - 1);
@@ -393,10 +390,10 @@ 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);
- DragManager.docsBeingDragged.forEach(d => (d[this.pivotField] = colHeader));
+ DragManager.docsBeingDragged.forEach(d => (d[this.notetakingCategoryField] = colHeader));
// used to notify sections to re-render
- // console.log([dropInd, this.getColumnFromXCoord(xCoord)])
- this.docsDraggedRowCol = [dropInd, this.getColumnFromXCoord(xCoord)];
+ this.docsDraggedRowCol.length = 0;
+ this.docsDraggedRowCol.push(dropInd, this.getColumnFromXCoord(xCoord));
}
};
@@ -425,7 +422,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (docs) {
docs.map(d => {
if (d instanceof Promise) return;
- const sectionValue = d[this.pivotField] as object;
+ const sectionValue = d[this.notetakingCategoryField] as object;
if (sectionValue.toString() == colHeader) {
docsMatchingHeader.push(d);
}
@@ -436,11 +433,22 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
@undoBatch
@action
+ onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
+ const docView = fieldProps.DocumentView?.();
+ if (docView && (e.ctrlKey || docView.rootDoc._singleLine) && ['Enter'].includes(e.key)) {
+ e.stopPropagation?.();
+ const newDoc = Doc.MakeCopy(docView.rootDoc, true);
+ Doc.GetProto(newDoc).text = undefined;
+ FormattedTextBox.SelectOnLoad = newDoc[Id];
+ return this.addDocument?.(newDoc);
+ }
+ };
+
+ @undoBatch
+ @action
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.docDragData) {
if (super.onInternalDrop(e, de)) {
- DragManager.docsBeingDragged = [];
- // this.docsDraggedRowCol = []
// filter out the currently dragged docs from the child docs, since we will insert them later
const rowCol = this.docsDraggedRowCol;
const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= this.childDocs.length); // 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).
@@ -456,10 +464,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (rowCol[0] <= 0) {
docs.splice(0, 0, ...newDocs);
} else {
- const colDocs = this.getDocsFromXCoord(de.x);
+ const colDocs = this.getDocsFromXCoord(this.props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]);
const previousDoc = colDocs[rowCol[0] - 1];
const previousDocIndex = docs.indexOf(previousDoc);
- console.log(`docs: ${previousDocIndex}`);
docs.splice(previousDocIndex + 1, 0, ...newDocs);
}
}
@@ -561,7 +568,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
renderChildren={this.children}
numGroupColumns={this.numGroupColumns}
gridGap={this.gridGap}
- pivotField={this.pivotField}
+ pivotField={this.notetakingCategoryField}
columnStartXCoords={this.columnStartXCoords}
maxColWidth={this.maxColWdith}
PanelWidth={this.PanelWidth}
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index bdcb9c399..55d032498 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,27 +1,27 @@
-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 { Id } from "../../../fields/FieldSymbols";
-import { RichTextField } from "../../../fields/RichTextField";
-import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { ScriptField } from "../../../fields/ScriptField";
-import { ImageField } from "../../../fields/URLField";
-import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, returnEmptyString, setupMoveUpEvents } 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 { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
-import "./CollectionNoteTakingView.scss";
-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 { Id } from '../../../fields/FieldSymbols';
+import { RichTextField } from '../../../fields/RichTextField';
+import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { ScriptField } from '../../../fields/ScriptField';
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
+import { emptyFunction, returnEmptyString, setupMoveUpEvents } 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 { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import './CollectionNoteTakingView.scss';
+const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -39,7 +39,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[];
renderChildren: (docs: Doc[]) => JSX.Element[];
addDocument: (doc: Doc | Doc[]) => boolean;
@@ -48,37 +48,37 @@ interface CSVFieldColumnProps {
observeHeight: (myref: any) => void;
unobserveHeight: (myref: any) => void;
editableViewProps: any;
- resizeColumns: (n: number) => void
- columnStartXCoords: number[]
- PanelWidth: number
- maxColWidth: number
+ resizeColumns: (n: number) => void;
+ columnStartXCoords: number[];
+ PanelWidth: number;
+ maxColWidth: number;
// docsByColumnHeader: Map<string, Doc[]>
// setDocsForColHeader: (key: string, docs: Doc[]) => void
}
@observer
export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColumnProps> {
- @observable private _background = "inherit";
+ @observable private _background = 'inherit';
@computed get columnWidth() {
- // base cases
- if (!this.props.columnHeaders || !this.props.headingObject || this.props.columnHeaders.length == 1) {
- return this.props.maxColWidth
- }
- const i = this.props.columnHeaders.indexOf(this.props.headingObject)
- if (i < 0) {
- return this.props.maxColWidth
- }
- const endColValue = i == this.props.numGroupColumns - 1 ? this.props.PanelWidth : this.props.columnStartXCoords[i+1]
- // TODO make the math work here. 35 is half of 70, which is the current width of the divider
- return endColValue - this.props.columnStartXCoords[i] - 30
+ // base cases
+ if (!this.props.columnHeaders || !this.props.headingObject || this.props.columnHeaders.length == 1) {
+ return this.props.maxColWidth;
+ }
+ const i = this.props.columnHeaders.indexOf(this.props.headingObject);
+ if (i < 0) {
+ return this.props.maxColWidth;
+ }
+ const endColValue = i == this.props.numGroupColumns - 1 ? this.props.PanelWidth : this.props.columnStartXCoords[i + 1];
+ // TODO make the math work here. 35 is half of 70, which is the current width of the divider
+ return endColValue - this.props.columnStartXCoords[i] - 30;
}
private dropDisposer?: DragManager.DragDropDisposer;
private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
@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;
// This is likely similar to what we will be doing. Why do we need to make these refs?
@@ -90,7 +90,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
this.props.observeHeight(ele);
this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
}
- }
+ };
componentWillUnmount() {
this.props.unobserveHeight(this._ele);
@@ -105,10 +105,10 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
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) => {
@@ -117,7 +117,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
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;
@@ -125,11 +125,11 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
return true;
}
return false;
- }
+ };
- @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) => {
@@ -139,46 +139,46 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
const colValue = this.getValue(this.props.heading);
newDoc[key] = colValue;
FormattedTextBox.SelectOnLoad = newDoc[Id];
- FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? "" : " ";
+ FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
return this.props.addDocument?.(newDoc) || false;
- }
+ };
@action
deleteColumn = () => {
if (!this.props.columnHeaders) {
- return
+ return;
}
if (this.props.headingObject) {
- const index = this.props.columnHeaders.indexOf(this.props.headingObject);
- const newIndex = index == 0 ? 1 : index - 1
- const newHeader = this.props.columnHeaders[newIndex];
- this.props.docList.forEach(d => d[this.props.pivotField] = newHeader.heading.toString())
- this.props.columnHeaders.splice(index, 1);
- this.props.resizeColumns(this.props.columnHeaders.length)
+ const index = this.props.columnHeaders.indexOf(this.props.headingObject);
+ const newIndex = index == 0 ? 1 : index - 1;
+ const newHeader = this.props.columnHeaders[newIndex];
+ this.props.docList.forEach(d => (d[this.props.pivotField] = newHeader.heading.toString()));
+ this.props.columnHeaders.splice(index, 1);
+ this.props.resizeColumns(this.props.columnHeaders.length);
}
- }
+ };
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[]) => {
- console.log('in startDrag')
+ console.log('in startDrag');
// 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._width = this.columnWidth;
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) {
- const options = {hideSource: false}
+ const options = { hideSource: false };
DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY, options);
- console.log('in startDrag')
+ console.log('in startDrag');
return true;
}
return false;
- }
+ };
menuCallback = (x: number, y: number) => {
ContextMenu.Instance.clearItems();
@@ -187,44 +187,62 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
const dataDoc = this.props.DataDoc || this.props.Document;
const pivotValue = this.getValue(this.props.heading);
- DocUtils.addDocumentCreatorMenuItems((doc) => {
- const key = this.props.pivotField;
- doc[key] = this.getValue(this.props.heading);
- FormattedTextBox.SelectOnLoad = doc[Id];
- return this.props.addDocument?.(doc);
- }, this.props.addDocument, x, y, true, this.props.pivotField, pivotValue);
+ DocUtils.addDocumentCreatorMenuItems(
+ doc => {
+ const key = this.props.pivotField;
+ doc[key] = this.getValue(this.props.heading);
+ FormattedTextBox.SelectOnLoad = doc[Id];
+ return this.props.addDocument?.(doc);
+ },
+ this.props.addDocument,
+ x,
+ y,
+ true,
+ this.props.pivotField,
+ pivotValue
+ );
- 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.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" });
- !Doc.UserDoc().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.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' });
+ !Doc.UserDoc().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);
@@ -233,98 +251,100 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
}
});
ContextMenu.Instance.displayMenu(x, y, undefined, true);
- }
+ };
@computed get innards() {
TraceMobx();
const key = this.props.pivotField;
const heading = this._heading;
const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin;
- const evContents = heading ? heading : "25";
- const headingView = this.props.headingObject ?
- <div key={heading} className="collectionNoteTakingView-sectionHeader" ref={this._headerRef}
+ const evContents = heading ? heading : '25';
+ const headingView = this.props.headingObject ? (
+ <div
+ key={heading}
+ className="collectionNoteTakingView-sectionHeader"
+ ref={this._headerRef}
style={{
marginTop: 2 * this.props.yMargin,
// width: (this.props.columnWidth) /
// ((uniqueHeadings.length) || 1)
- width: this.columnWidth - 20
+ width: this.columnWidth - 20,
}}>
- <div className="collectionNoteTakingView-sectionHeader-subCont" onPointerDown={this.headerDown}
- title={evContents === `No Value` ?
- `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
- style={{ background: evContents !== `No Value` ? this._color : "inherit" }}>
- <EditableView
- GetValue={() => evContents}
- SetValue={this.headingChanged}
- contents={evContents}
- oneLine={true}
- />
+ <div
+ className="collectionNoteTakingView-sectionHeader-subCont"
+ onPointerDown={this.headerDown}
+ title={evContents === `No Value` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
+ style={{ background: evContents !== `No Value` ? this._color : 'inherit' }}>
+ <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
</div>
- </div> : (null);
+ </div>
+ ) : null;
// const templatecols = `${this.props.columnWidth / this.props.numGroupColumns}px `;
const templatecols = `${this.columnWidth}px `;
const type = this.props.Document.type;
- return <>
- {headingView}
- {<div>
- <div key={`${heading}-stack`} className={`collectionNoteTakingView-Nodes`}
- 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`,
- height: 'max-content',
- position: "relative",
- gridGap: this.props.gridGap,
- gridTemplateColumns: templatecols,
- gridAutoRows: "0px"
- }}>
- {this.props.renderChildren(this.props.docList)}
- </div>
+ return (
+ <>
+ {headingView}
+ {
+ <div>
+ <div
+ key={`${heading}-stack`}
+ className={`collectionNoteTakingView-Nodes`}
+ 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`,
+ height: 'max-content',
+ position: 'relative',
+ gridGap: this.props.gridGap,
+ gridTemplateColumns: templatecols,
+ gridAutoRows: '0px',
+ }}>
+ {this.props.renderChildren(this.props.docList)}
+ </div>
- {!this.props.chromeHidden && type !== DocumentType.PRES ?
- <div className="collectionNoteTakingView-DocumentButtons"
- // style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10 }}>
- style={{ width: this.columnWidth - 20, marginBottom: 10 }}>
- <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton">
- <EditableView
- GetValue={returnEmptyString}
- SetValue={this.addNewTextDoc}
- textCallback={this.textCallback}
- placeholder={"Type ':' for commands"}
- contents={"+ New Node"}
- menuCallback={this.menuCallback}
- />
- </div>
- <div key={`${this.props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton">
- <EditableView {...this.props.editableViewProps} />
- </div>
- {(this.props.columnHeaders?.length && this.props.columnHeaders.length > 1) &&
- <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
- <FontAwesomeIcon icon="trash" size="lg" />
- </button>
- }
- </div>
- : null}
- </div>
- }
- </>;
+ {!this.props.chromeHidden && type !== DocumentType.PRES ? (
+ <div
+ className="collectionNoteTakingView-DocumentButtons"
+ // style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10 }}>
+ style={{ width: this.columnWidth - 20, marginBottom: 10 }}>
+ <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton">
+ <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.textCallback} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} />
+ </div>
+ <div key={`${this.props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton">
+ <EditableView {...this.props.editableViewProps} />
+ </div>
+ {this.props.columnHeaders?.length && this.props.columnHeaders.length > 1 && (
+ <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
+ <FontAwesomeIcon icon="trash" size="lg" />
+ </button>
+ )}
+ </div>
+ ) : null}
+ </div>
+ }
+ </>
+ );
}
-
render() {
TraceMobx();
const heading = this._heading;
return (
- <div className={"collectionNoteTakingViewFieldColumn" + (SnappingManager.GetIsDragging() ? "Dragging" : "")} key={heading}
+ <div
+ className={'collectionNoteTakingViewFieldColumn' + (SnappingManager.GetIsDragging() ? 'Dragging' : '')}
+ key={heading}
style={{
- //TODO: change this so that it's based on the column width
+ //TODO: change this so that it's based on the column width
width: this.columnWidth,
- height: "100%",
- background: this._background
+ height: '100%',
+ 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/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index ed5dc3715..7d31b3193 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -1,61 +1,63 @@
-import { action, observable } from "mobx";
-import * as React from "react";
+import { action, observable } from 'mobx';
+import * as React from 'react';
interface DividerProps {
- index: number
- xMargin: number
- setColumnStartXCoords: (movementX: number, colIndex: number) => void
+ index: number;
+ xMargin: number;
+ setColumnStartXCoords: (movementX: number, colIndex: number) => void;
}
-export default class Divider extends React.Component<DividerProps>{
- @observable private isHoverActive = false;
- @observable private isResizingActive = false;
-
- @action
- private registerResizing = (e: React.PointerEvent<HTMLDivElement>) => {
- e.stopPropagation();
- e.preventDefault();
- window.removeEventListener("pointermove", this.onPointerMove);
- window.removeEventListener("pointerup", this.onPointerUp);
- window.addEventListener("pointermove", this.onPointerMove);
- window.addEventListener("pointerup", this.onPointerUp);
- this.isResizingActive = true;
- }
+export class CollectionNoteTakingViewDivider extends React.Component<DividerProps> {
+ @observable private isHoverActive = false;
+ @observable private isResizingActive = false;
- @action
- private onPointerUp = () => {
- this.isResizingActive = false;
- this.isHoverActive = false;
- window.removeEventListener("pointermove", this.onPointerMove);
- window.removeEventListener("pointerup", this.onPointerUp);
- }
+ @action
+ private registerResizing = (e: React.PointerEvent<HTMLDivElement>) => {
+ e.stopPropagation();
+ e.preventDefault();
+ window.removeEventListener('pointermove', this.onPointerMove);
+ window.removeEventListener('pointerup', this.onPointerUp);
+ window.addEventListener('pointermove', this.onPointerMove);
+ window.addEventListener('pointerup', this.onPointerUp);
+ this.isResizingActive = true;
+ };
- @action
- onPointerMove = ({ movementX }: PointerEvent) => {
- this.props.setColumnStartXCoords(movementX, this.props.index)
- }
-
- render() {
- return (
- <div className="columnResizer"
- style={{
- display: "flex",
- alignItems: "center",
- cursor: "col-resize"
- }}
- onPointerEnter={action(() => this.isHoverActive = true)}
- onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}
- >
- <div className="columnResizer-handler" onPointerDown={e => this.registerResizing(e)}
- style={{
- height: "95%",
- width: 12,
- borderRight: "4px solid #282828",
- borderLeft: "4px solid #282828",
- margin: "0px 10px"
- }}
- />
- </div>
- )
- }
-} \ No newline at end of file
+ @action
+ private onPointerUp = () => {
+ this.isResizingActive = false;
+ this.isHoverActive = false;
+ window.removeEventListener('pointermove', this.onPointerMove);
+ window.removeEventListener('pointerup', this.onPointerUp);
+ };
+
+ @action
+ onPointerMove = ({ movementX }: PointerEvent) => {
+ this.props.setColumnStartXCoords(movementX, this.props.index);
+ };
+
+ render() {
+ return (
+ <div
+ className="columnResizer"
+ style={{
+ display: 'flex',
+ alignItems: 'center',
+ cursor: 'col-resize',
+ }}
+ onPointerEnter={action(() => (this.isHoverActive = true))}
+ onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}>
+ <div
+ className="columnResizer-handler"
+ onPointerDown={e => this.registerResizing(e)}
+ style={{
+ height: '95%',
+ width: 12,
+ borderRight: '4px solid #282828',
+ borderLeft: '4px solid #282828',
+ margin: '0px 10px',
+ }}
+ />
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 1927db51e..ef68cadd7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -447,8 +447,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
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.
const docs = this.childDocList;
- // reset drag manager docs, because we just dropped
- DragManager.docsBeingDragged = [];
// still figuring out where to add the document
if (docs && newDocs.length) {
const insertInd = dropInd === -1 ? docs.length : dropInd + dropAfter;
@@ -456,6 +454,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
newDocs.filter(ndoc => docs.indexOf(ndoc) !== -1).forEach(ndoc => docs.splice(docs.indexOf(ndoc), 1));
docs.splice(insertInd - offset, 0, ...newDocs);
}
+ // reset drag manager docs, because we just dropped
+ DragManager.docsBeingDragged.length = 0;
}
} else if (de.complete.linkDragData?.dragDocument.context === this.props.Document && de.complete.linkDragData?.linkDragView?.props.CollectionFreeFormDocumentView?.()) {
const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, _fitWidth: true, title: 'dropped annotation' });
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index afb618b34..1ee1aec5a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -156,9 +156,7 @@ export interface DocumentViewSharedProps {
scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
createNewFilterDoc?: () => void;
updateFilterDoc?: (doc: Doc) => void;
- // Parker added both of these
- originalBackgroundColor?: string;
- isNoteTakingView?: boolean;
+ dontHideOnDrag?: boolean;
}
// these props are specific to DocuentViews
@@ -494,12 +492,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) {
if (this._mainCont.current) {
const dragData = new DragManager.DocumentDragData([this.props.Document]);
- if (this.props.isNoteTakingView) {
- dragData.draggedDocuments.forEach((doc) => {
- doc.backgroundColor = "#C9DAEF";
- doc.opacity = 0.5;
- });
- }
const [left, top] = this.props.ScreenToLocalTransform().scale(this.NativeDimScaling).inverse().transformPoint(0, 0);
dragData.offset = this.props
.ScreenToLocalTransform()
@@ -511,22 +503,16 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
dragData.treeViewDoc = this.props.treeViewDoc;
dragData.removeDocument = this.props.removeDocument;
dragData.moveDocument = this.props.moveDocument;
- //dragData.dimSource :
- // dragEffects field, set dim
+ //dragData.dimSource :
+ // dragEffects field, set dim
// add kv pairs to a doc, swap properties with the node while dragging, and then swap when dropping
// add a dragEffects prop to DocumentView as a function that sets up. Each view has its own prop, when you start dragging:
- // in Draganager, figure out which doc(s) you're dragging and change what opacity function returns
+ // in Draganager, figure out which doc(s) you're dragging and change what opacity function returns
const ffview = this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
- ffview && runInAction(() => (ffview.ChildDrag = this.props.DocumentView()));
- DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStar && !this.props.isNoteTakingView)},
- () => setTimeout(action(() => {
- ffview && (ffview.ChildDrag = undefined)
- //TODO: is there a better way than adding another field to the props? Not quite sure how "this" works tbh
- if (this.props.isNoteTakingView) {
- this.props.Document.backgroundColor = "";
- this.props.Document.opacity = 1;
- }
- }))); // this needs to happen after the drop event is processed.
+ ffview && runInAction(() => (ffview.ChildDrag = this.props.DocumentView()));
+ DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStart && !this.props.dontHideOnDrag) }, () =>
+ setTimeout(action(() => ffview && (ffview.ChildDrag = undefined)))
+ ); // this needs to happen after the drop event is processed.
ffview?.setupDragLines(false);
}
}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index b8ee89ef2..add83f4e0 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1001,7 +1001,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
() => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, autoHeight: this.autoHeight, marginsHeight: this.autoHeightMargins }),
({ sidebarHeight, textHeight, autoHeight, marginsHeight }) => {
const newHeight = this.contentScaling * (marginsHeight + Math.max(sidebarHeight, textHeight));
- autoHeight && newHeight && this.props.setHeight?.(newHeight);
+ if (autoHeight && newHeight && newHeight !== this.rootDoc.height) {
+ this.props.setHeight?.(newHeight);
+ }
},
{ fireImmediately: true }
);
@@ -1695,7 +1697,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (this.props.setHeight && scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) {
// if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
const setScrollHeight = () => (this.rootDoc[this.fieldKey + '-scrollHeight'] = scrollHeight);
- if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) {
+ if (this.rootDoc === this.layoutDoc || this.layoutDoc.resolvedDataDoc) {
setScrollHeight();
} else {
setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived...