aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.scss9
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx80
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx2
4 files changed, 73 insertions, 22 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingView.scss b/src/client/views/collections/CollectionNoteTakingView.scss
index 81000e7a5..95fda7b0a 100644
--- a/src/client/views/collections/CollectionNoteTakingView.scss
+++ b/src/client/views/collections/CollectionNoteTakingView.scss
@@ -494,6 +494,15 @@
.rc-switch-checked .rc-switch-inner {
left: 8px;
}
+
+ .collectionNoteTaking-pivotField {
+ display: none;
+ }
+ &:hover {
+ .collectionNoteTaking-pivotField {
+ display: unset;
+ }
+ }
}
.collectionNoteTakingViewLight {
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 5c52d2398..d8a0aebb1 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -14,9 +14,10 @@ import { Docs, DocUtils } from '../../documents/Documents';
import { DragManager, dropActionType } from '../../util/DragManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoable, undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
+import { Colors } from '../global/globalEnums';
import { LightboxView } from '../LightboxView';
import { DocumentView } from '../nodes/DocumentView';
import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView';
@@ -26,7 +27,7 @@ import './CollectionNoteTakingView.scss';
import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
import { CollectionSubView } from './CollectionSubView';
-import { Colors } from '../global/globalEnums';
+import { FieldsDropdown } from '../FieldsDropdown';
const _global = (window /* browser */ || global) /* node */ as any;
/**
@@ -42,7 +43,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
_masonryGridRef: HTMLDivElement | null = null;
_draggerRef = React.createRef<HTMLDivElement>();
@computed get notetakingCategoryField() {
- return StrCast(this.dataDoc.notetaking_category, 'NotetakingCategory');
+ return StrCast(this.dataDoc.notetaking_column, StrCast(this.layoutDoc.pivotField, 'notetaking_column'));
}
public DividerWidth = 16;
@observable docsDraggedRowCol: number[] = [];
@@ -155,25 +156,34 @@ export class CollectionNoteTakingView extends CollectionSubView() {
);
};
+ @computed get allFieldValues() {
+ return new Set(this.childDocs.map(doc => StrCast(doc[this.notetakingCategoryField])));
+ }
+
componentDidMount() {
super.componentDidMount?.();
document.addEventListener('pointerup', this.removeDocDragHighlight, true);
- this._disposers.layout_autoHeight = reaction(
- () => this.layoutDoc._layout_autoHeight,
- layout_autoHeight => layout_autoHeight && this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight)))
+
+ this._disposers.autoColumns = reaction(
+ () => (this.layoutDoc._notetaking_columns_autoCreate ? Array.from(this.allFieldValues) : undefined),
+ columns => undoable(() => columns?.filter(col => !this.colHeaderData.some(h => h.heading === col)).forEach(col => this.addColumn(col)), 'adding columns')(),
+ { fireImmediately: true }
);
this._disposers.refList = reaction(
() => ({ refList: this._refList.slice(), autoHeight: this.layoutDoc._layout_autoHeight && !LightboxView.Contains(this.DocumentView?.()) }),
({ refList, autoHeight }) => {
- if (autoHeight) refList.forEach(r => this.observer.observe(r));
- else this.observer.disconnect();
+ if (autoHeight) {
+ refList.forEach(r => this.observer.observe(r));
+ this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight)));
+ } else this.observer.disconnect();
},
{ fireImmediately: true }
);
}
componentWillUnmount() {
+ this.observer.disconnect();
document.removeEventListener('pointerup', this.removeDocDragHighlight, true);
super.componentWillUnmount();
Object.keys(this._disposers).forEach(key => this._disposers[key]());
@@ -300,7 +310,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
getDocWidth(d: Doc) {
const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as Field);
const existingHeader = this.colHeaderData.find(sh => sh.heading === heading);
- const existingWidth = existingHeader?.width ? existingHeader.width : 0;
+ const existingWidth = this.layoutDoc._notetaking_columns_autoSize ? 1 / (this.colHeaderData.length ?? 1) : existingHeader?.width ? existingHeader.width : 0;
const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth;
const width = d.layout_fitWidth ? maxWidth : NumCast(d._width);
return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth);
@@ -502,7 +512,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
editableViewProps = () => ({
GetValue: () => '',
- SetValue: this.addGroup,
+ SetValue: this.addColumn,
contents: '+ Column',
});
@@ -543,18 +553,26 @@ export class CollectionNoteTakingView extends CollectionSubView() {
/>
);
+ @undoBatch
+ remColumn = (value: SchemaHeaderField) => {
+ const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
+ if (value) {
+ const index = colHdrData.indexOf(value);
+ index !== -1 && colHdrData.splice(index, 1);
+ this.resizeColumns(colHdrData);
+ }
+ };
+
// addGroup is called when adding a new columnHeader, adding a SchemaHeaderField to our list of
// columnHeaders and resizing the existing columns to make room for our new one.
@undoBatch
- addGroup = (value: string) => {
- if (this.colHeaderData) {
- for (const header of this.colHeaderData) {
- if (header.heading === value) {
- alert('You cannot use an existing column name. Please try a new column name');
- return value;
- }
+ addColumn = (value: string) => {
+ this.colHeaderData.forEach(header => {
+ if (header.heading === value) {
+ alert('You cannot use an existing column name. Please try a new column name');
+ return value;
}
- }
+ });
const columnHeaders = Array.from(Cast(this.dataDoc[this.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
const newColWidth = 1 / (this.numGroupColumns + 1);
columnHeaders.push(new SchemaHeaderField(value, undefined, undefined, newColWidth));
@@ -562,11 +580,25 @@ export class CollectionNoteTakingView extends CollectionSubView() {
return true;
};
+ removeEmptyColumns = undoable(() => {
+ this.colHeaderData.filter(h => !this.allFieldValues.has(h.heading)).forEach(this.remColumn);
+ }, 'remove empty Columns');
+
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
if (!e.isPropagationStopped()) {
const subItems: ContextMenuProps[] = [];
- subItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => (this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill), icon: 'plus' });
+ subItems.push({
+ description: `${this.layoutDoc._notetaking_columns_autoCreate ? 'Manually' : 'Automatically'} Create columns`,
+ event: () => (this.layoutDoc._notetaking_columns_autoCreate = !this.layoutDoc._notetaking_columns_autoCreate),
+ icon: 'computer',
+ });
+ subItems.push({ description: 'Remove Empty Columns', event: this.removeEmptyColumns, icon: 'computer' });
+ subItems.push({
+ description: `${this.layoutDoc._notetaking_columns_autoSize ? 'Variable Size' : 'Autosize'} Columns`,
+ event: () => (this.layoutDoc._notetaking_columns_autoSize = !this.layoutDoc._notetaking_columns_autoSize),
+ icon: 'plus',
+ });
subItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => (this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight), icon: 'plus' });
subItems.push({ description: 'Clear All', event: () => (this.dataDoc.data = new List([])), icon: 'times' });
ContextMenu.Instance.addItem({ description: 'Options...', subitems: subItems, icon: 'eye' });
@@ -634,6 +666,16 @@ export class CollectionNoteTakingView extends CollectionSubView() {
onContextMenu={this.onContextMenu}
onWheel={e => this._props.isContentActive() && e.stopPropagation()}>
<>{this.renderedSections}</>
+ <div className="collectionNotetaking-pivotField" style={{ right: 0, top: 0, position: 'absolute' }}>
+ <FieldsDropdown
+ Document={this.Document}
+ selectFunc={undoable(fieldKey => {
+ this.layoutDoc._pivotField = fieldKey;
+ this.removeEmptyColumns();
+ }, 'change pivot field')}
+ placeholder={StrCast(this.layoutDoc._pivotField)}
+ />
+ </div>
</div>
);
}
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index 788490b82..448b11b05 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { lightOrDark, returnEmptyString } from '../../../Utils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Id } from '../../../fields/FieldSymbols';
import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
@@ -68,6 +67,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
// columnWidth returns the width of a column in absolute pixels
@computed get columnWidth() {
+ if (this._props.Document._notetaking_columns_autoSize) return this._props.availableWidth / (this._props.colHeaderData?.length || 1);
if (!this._props.colHeaderData || !this._props.headingObject || this._props.colHeaderData.length === 1) return `${(this._props.availableWidth / this._props.PanelWidth()) * 100}%`;
const i = this._props.colHeaderData.findIndex(hd => hd.heading === this._props.headingObject?.heading && hd.color === this._props.headingObject.color);
return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%';
@@ -154,7 +154,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
deleteColumn = () => {
const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
if (this._props.headingObject) {
- this._props.docList.forEach(d => (d[this._props.pivotField] = undefined));
+ // this._props.docList.forEach(d => (d[DocData][this._props.pivotField] = undefined));
colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1);
this._props.resizeColumns(colHdrData);
}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index c2f3a6e4b..5c59f7f60 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1255,7 +1255,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
return !whichData ? undefined : { data: RTFCast(whichData), str: Field.toString(DocCast(whichData) ?? StrCast(whichData)) };
},
incomingValue => {
- if (this._editorView && this._applyingChange !== this.fieldKey) {
+ if (this._editorView && this._applyingChange !== this.fieldKey && incomingValue?.data !== this.dataDoc[this.fieldKey]) {
if (incomingValue?.data) {
const updatedState = JSON.parse(incomingValue.data.Data);
if (JSON.stringify(this._editorView.state.toJSON()) !== JSON.stringify(updatedState)) {