aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionNoteTakingViewColumn.tsx')
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx376
1 files changed, 184 insertions, 192 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index 0ee5985bb..4286da2e2 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,27 +1,29 @@
-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';
+import { listSpec } from '../../../fields/Schema';
+import { Cast } from '../../../fields/Types';
+const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -39,7 +41,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;
@@ -47,38 +49,39 @@ interface CSVFieldColumnProps {
screenToLocalTransform: () => Transform;
observeHeight: (myref: any) => void;
unobserveHeight: (myref: any) => void;
- editableViewProps: any;
- resizeColumns: (n: number) => void
- columnStartXCoords: number[]
- PanelWidth: number
- maxColWidth: number
+ //setDraggedCol:(clonedDiv:any, header:SchemaHeaderField, xycoors: )
+ editableViewProps: () => any;
+ 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 || i > this.props.columnStartXCoords.length - 1) {
+ 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 +93,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 +108,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 +120,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 +128,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,50 +142,21 @@ 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;
- }
+ };
+ @undoBatch
@action
@undoBatch
deleteColumn = () => {
- if (!this.props.columnHeaders) {
- 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);
- // const newHeaders = this.props.columnHeaders;
- // newHeaders.splice(index, 1);
- // this.props.columnHeaders = newHeaders;
- this.props.resizeColumns(this.props.columnHeaders.length)
+ const columnHeaders = Cast(this.props.Document.columnHeaders, listSpec(SchemaHeaderField), null);
+ if (columnHeaders && this.props.headingObject) {
+ const index = columnHeaders.indexOf(this.props.headingObject);
+ this.props.docList.forEach(d => (d[this.props.pivotField] = 'unset'));
+ columnHeaders.splice(index, 1);
}
- }
-
- headerDown = (e: React.PointerEvent<HTMLDivElement>) => setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
-
- //TODO: I think this is where I'm supposed to edit stuff
- startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
- 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;
- alias.viewSpecScript = ScriptField.MakeFunction(`doc.${this.props.pivotField} === ${value}`, { doc: Doc.name });
- if (alias.viewSpecScript) {
- const options = {hideSource: false}
- DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY, options);
- console.log('in startDrag')
- return true;
- }
- return false;
- }
+ };
menuCallback = (x: number, y: number) => {
ContextMenu.Instance.clearItems();
@@ -191,44 +165,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);
@@ -237,98 +229,98 @@ 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"
+ 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 style={{ height: '100%' }}>
+ <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
+ 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
+}