aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-05-16 14:50:29 -0400
committerbobzel <zzzman@gmail.com>2023-05-16 14:50:29 -0400
commit46cf6c823ca8ab628cd8c5bd7fdfe8945344a014 (patch)
tree1e49ff8b3c29a3e31ad96ec39dd337cb58136426 /src/client/views/collections
parentdf7257d1b39f51a7e00a495f0d4a2366f0e21f7d (diff)
fixed bugs with goldenlayout dragging and undoing. fixed searching for filter values in sidebars. Stopped creating empty list for collections when datafield() is accessed because it messes up undo of a collection. fixed tab title editing. from marquee. Added UndoStack UI and additional naming support in code.
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx63
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx5
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx3
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx4
-rw-r--r--src/client/views/collections/CollectionSubView.tsx13
-rw-r--r--src/client/views/collections/TabDocView.tsx21
-rw-r--r--src/client/views/collections/TreeView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx26
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx32
-rw-r--r--src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx2
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx10
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTableCell.tsx2
13 files changed, 83 insertions, 104 deletions
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index cce21a3aa..4ae24af60 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -6,7 +6,7 @@ import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
-import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
+import { ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { inheritParentAcls } from '../../../fields/util';
import { emptyFunction, incrementTitleCopy } from '../../../Utils';
@@ -20,14 +20,14 @@ import { SelectionManager } from '../../util/SelectionManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
import { DashboardView } from '../DashboardView';
import { LightboxView } from '../LightboxView';
+import { OpenWhere, OpenWhereMod } from '../nodes/DocumentView';
+import { OverlayView } from '../OverlayView';
+import { ScriptingRepl } from '../ScriptingRepl';
import './CollectionDockingView.scss';
import { CollectionFreeFormView } from './collectionFreeForm';
import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
import { TabDocView } from './TabDocView';
import React = require('react');
-import { OpenWhere, OpenWhereMod } from '../nodes/DocumentView';
-import { OverlayView } from '../OverlayView';
-import { ScriptingRepl } from '../ScriptingRepl';
const _global = (window /* browser */ || global) /* node */ as any;
@observer
@@ -85,6 +85,7 @@ export class CollectionDockingView extends CollectionSubView() {
tabItemDropped = () => DragManager.CompleteWindowDrag?.(false);
tabDragStart = (proxy: any, finishDrag?: (aborted: boolean) => void) => {
+ this._flush = this._flush ?? UndoManager.StartBatch('tab move');
const dashDoc = proxy?._contentItem?.tab?.DashDoc as Doc;
dashDoc && (DragManager.DocDragData = new DragManager.DocumentDragData([proxy._contentItem.tab.DashDoc]));
DragManager.CompleteWindowDrag = (aborted: boolean) => {
@@ -92,12 +93,12 @@ export class CollectionDockingView extends CollectionSubView() {
proxy._dragListener.AbortDrag();
if (this._flush) {
this._flush.cancel(); // cancel the undo change being logged
- this._flush = undefined;
this.setupGoldenLayout(); // restore golden layout to where it was before the drag (this is a no-op when using StartOtherDrag because the proxy dragged item was never in the golden layout)
}
DragManager.CompleteWindowDrag = undefined;
}
finishDrag?.(aborted);
+ setTimeout(this.endUndoBatch, 100);
};
};
@undoBatch
@@ -180,7 +181,6 @@ export class CollectionDockingView extends CollectionSubView() {
//
// Creates a split on any side of the docking view based on the passed input pullSide and then adds the Document to the requested side
//
- @undoBatch
@action
public static AddSplit(document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) {
if (document?._type_collection === CollectionViewType.Docking) return DashboardView.openDashboard(document);
@@ -195,6 +195,8 @@ export class CollectionDockingView extends CollectionSubView() {
if (!instance) return false;
const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName, undefined, keyValue);
+ CollectionDockingView.Instance._flush = CollectionDockingView.Instance._flush ?? UndoManager.StartBatch('Add Split');
+ setTimeout(CollectionDockingView.Instance.endUndoBatch, 100);
if (!pullSide && stack) {
stack.addChild(docContentConfig, undefined);
setTimeout(() => stack.setActiveContentItem(stack.contentItems[stack.contentItems.length - 1]));
@@ -370,16 +372,30 @@ export class CollectionDockingView extends CollectionSubView() {
!LightboxView.LightboxDoc && cur && this._goldenLayout?.updateSize(cur.getBoundingClientRect().width, cur.getBoundingClientRect().height);
};
+ endUndoBatch = () => {
+ const json = JSON.stringify(this._goldenLayout.toConfig());
+ const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', ''));
+ const docs = !docids
+ ? []
+ : docids
+ .map(id => DocServer.GetCachedRefField(id))
+ .filter(f => f)
+ .map(f => f as Doc);
+ const changesMade = this.props.Document.dockingConfig !== json;
+ if (changesMade) {
+ this.props.Document.dockingConfig = json;
+ this.props.Document.data = new List<Doc>(docs);
+ }
+ this._flush?.end();
+ this._flush = undefined;
+ };
+
@action
onPointerUp = (e: MouseEvent): void => {
window.removeEventListener('pointerup', this.onPointerUp);
- const flush = this._flush;
- this._flush = undefined;
- if (flush) {
- DragManager.CompleteWindowDrag = undefined;
- if (!this.stateChanged()) flush.cancel();
- else flush.end();
- }
+ DragManager.CompleteWindowDrag = undefined;
+ setTimeout(this.endUndoBatch, 100);
};
@action
@@ -393,10 +409,8 @@ export class CollectionDockingView extends CollectionSubView() {
window.addEventListener('mouseup', this.onPointerUp);
if (!htmlTarget.closest('*.lm_content') && (htmlTarget.closest('*.lm_tab') || htmlTarget.closest('*.lm_stack'))) {
const className = typeof htmlTarget.className === 'string' ? htmlTarget.className : '';
- if (!className.includes('lm_close') && !className.includes('lm_maximise')) {
- this._flush = UndoManager.StartBatch('golden layout edit');
- DocServer.UPDATE_SERVER_CACHE();
- }
+ if (className.includes('lm_maximise')) this._flush = UndoManager.StartBatch('tab maximize');
+ else if (!className.includes('lm_close')) DocServer.UPDATE_SERVER_CACHE();
}
}
if (!InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
@@ -452,25 +466,12 @@ export class CollectionDockingView extends CollectionSubView() {
stateChanged = () => {
this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
const json = JSON.stringify(this._goldenLayout.toConfig());
- const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
- const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', ''));
- const docs = !docids
- ? []
- : docids
- .map(id => DocServer.GetCachedRefField(id))
- .filter(f => f)
- .map(f => f as Doc);
const changesMade = this.props.Document.dockingConfig !== json;
- if (changesMade && !this._flush) {
- UndoManager.RunInBatch(() => {
- this.props.Document.dockingConfig = json;
- this.props.Document.data = new List<Doc>(docs);
- }, 'state changed');
- }
return changesMade;
};
tabDestroyed = (tab: any) => {
+ this._flush = this._flush ?? UndoManager.StartBatch('tab movement');
if (tab.DashDoc && ![DocumentType.KVP, DocumentType.PRES].includes(tab.DashDoc?.type)) {
Doc.AddDocToList(Doc.MyHeaderBar, 'data', tab.DashDoc);
Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', tab.DashDoc, undefined, true, true);
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index 63becac1e..2f28ecd00 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -121,7 +121,8 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
@action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4');
@action pointerLeave = () => (this._background = 'inherit');
- textCallback = (char: string) => this.addNewTextDoc('-typed text-', false, true);
+ @undoBatch
+ addTextNote = (char: string) => this.addNewTextDoc('-typed text-', false, true);
// addNewTextDoc is called when a user starts typing in a column to create a new node
@action
@@ -272,7 +273,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
{!this.props.chromeHidden ? (
<div className="collectionNoteTakingView-DocumentButtons" style={{ 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} />
+ <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} 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()} />
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 6b4c8a3e9..b131d38d8 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -119,7 +119,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
// onClick play scripts
CollectionStackedTimeline.RangeScript =
CollectionStackedTimeline.RangeScript ||
- ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, {
+ ScriptField.MakeFunction(`setTimeout(() => scriptContext.clickAnchor(this, clientX))`, {
+ // setTimeout is a hack to run script in its own properly named undo group (instead of being part of the generic onClick)
self: Doc.name,
scriptContext: 'any',
clientX: 'number',
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 243550c0b..6be9cb72d 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -128,7 +128,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
@action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4');
@action pointerLeave = () => (this._background = 'inherit');
- textCallback = (char: string) => this.addNewTextDoc('-typed text-', false, true);
+ @undoBatch typedNote = (char: string) => this.addNewTextDoc('-typed text-', false, true);
@action
addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
@@ -363,7 +363,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
<EditableView
GetValue={returnEmptyString}
SetValue={this.addNewTextDoc}
- textCallback={this.textCallback}
+ textCallback={this.typedNote}
placeholder={"Type ':' for commands"}
contents={<FontAwesomeIcon icon={'plus'} />}
menuCallback={this.menuCallback}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index bcda13c8b..cfe78afa1 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -5,7 +5,6 @@ import { AclPrivate, Doc, DocListCast, Field, Opt, StrListCast } from '../../../
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
-import { ScriptField } from '../../../fields/ScriptField';
import { Cast, ScriptCast, StrCast } from '../../../fields/Types';
import { WebField } from '../../../fields/URLField';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
@@ -65,11 +64,7 @@ export function CollectionSubView<X>(moreProps?: X) {
// to its children which may be templates.
// If 'annotationField' is specified, then all children exist on that field of the extension document, otherwise, they exist directly on the data document under 'fieldKey'
@computed get dataField() {
- if (this.layoutDoc[this.props.fieldKey]) return this.layoutDoc[this.props.fieldKey];
- // sets the dataDoc's data field to an empty list if the data field is undefined - prevents issues with addonly
- // setTimeout changes it outside of the @computed section
- !this.dataDoc[this.props.fieldKey] && setTimeout(() => !this.dataDoc[this.props.fieldKey] && (this.dataDoc[this.props.fieldKey] = new List<Doc>()));
- return this.dataDoc[this.props.fieldKey];
+ return this.layoutDoc[this.props.fieldKey];
}
get childLayoutPairs(): { layout: Doc; data: Doc }[] {
@@ -130,8 +125,9 @@ export function CollectionSubView<X>(moreProps?: X) {
const fieldKey = Doc.LayoutFieldKey(d);
const annos = !Field.toString(Doc.LayoutField(d) as Field).includes(CollectionView.name);
const data = d[annos ? fieldKey + '_annotations' : fieldKey];
- if (data !== undefined) {
- let subDocs = DocListCast(data);
+ const side = annos && d[fieldKey + '_sidebar'];
+ if (data !== undefined || side !== undefined) {
+ let subDocs = [...DocListCast(data), ...DocListCast(side)];
if (subDocs.length > 0) {
let newarray: Doc[] = [];
notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, childDocFilters, docRangeFilters, d).length);
@@ -142,6 +138,7 @@ export function CollectionSubView<X>(moreProps?: X) {
const annos = !Field.toString(Doc.LayoutField(t) as Field).includes(CollectionView.name);
notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!childDocFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([t], childDocFilters, docRangeFilters, d).length));
DocListCast(t[annos ? fieldKey + '_annotations' : fieldKey]).forEach(newdoc => newarray.push(newdoc));
+ annos && DocListCast(t[fieldKey + '_sidebar']).forEach(newdoc => newarray.push(newdoc));
});
subDocs = newarray;
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 7e88959a4..33fa434e1 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -13,14 +13,13 @@ import { listSpec } from '../../../fields/Schema';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from '../../../Utils';
import { DocServer } from '../../DocServer';
-import { DocUtils } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType } from '../../util/DragManager';
import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch, UndoManager } from '../../util/UndoManager';
+import { undoable, UndoManager } from '../../util/UndoManager';
import { DashboardView } from '../DashboardView';
import { Colors, Shadows } from '../global/globalEnums';
import { LightboxView } from '../LightboxView';
@@ -116,15 +115,13 @@ export class TabDocView extends React.Component<TabDocViewProps> {
titleEle.size = StrCast(doc.title).length + 3;
titleEle.value = doc.title;
- titleEle.onkeydown = (e: KeyboardEvent) => {
- e.stopPropagation();
- };
- titleEle.onchange = undoBatch(
- action((e: any) => {
+ titleEle.onkeydown = (e: KeyboardEvent) => e.stopPropagation();
+ titleEle.onchange = (e: any) => {
+ undoable(() => {
titleEle.size = e.currentTarget.value.length + 3;
Doc.GetProto(doc).title = e.currentTarget.value;
- })
- );
+ }, 'edit tab title')();
+ };
if (tab.element[0].children[1].children.length === 1) {
iconWrap.className = 'lm_iconWrap lm_moreInfo';
@@ -198,7 +195,9 @@ export class TabDocView extends React.Component<TabDocViewProps> {
action(selected => {
if (selected) this._activated = true;
const toggle = tab.element[0].children[2].children[0] as HTMLInputElement;
- selected && tab.contentItem !== tab.header.parent.getActiveContentItem() && UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), 'tab switch');
+ if (selected && tab.contentItem !== tab.header.parent.getActiveContentItem()) {
+ undoable(() => tab.header.parent.setActiveContentItem(tab.contentItem), 'tab switch')();
+ }
toggle.style.fontWeight = selected ? 'bold' : '';
// toggle.style.textTransform = selected ? "uppercase" : "";
}),
@@ -234,7 +233,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
public static PinDoc(docs: Doc | Doc[], pinProps: PinProps) {
const docList = docs instanceof Doc ? [docs] : docs;
- const batch = UndoManager.StartBatch('pinning doc');
+ const batch = UndoManager.StartBatch('Pin doc to pres trail');
const curPres = Doc.ActivePresentation ?? Doc.MakeCopy(Doc.UserDoc().emptyTrail as Doc, true);
if (!Doc.ActivePresentation) {
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 037148bb9..f56eaee07 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -102,7 +102,7 @@ export class TreeView extends React.Component<TreeViewProps> {
private _treedropDisposer?: DragManager.DragDropDisposer;
get treeViewOpenIsTransient() {
- return this.props.treeView.doc.treeViewOpenIsTransient || Doc.IsDocDataProto(this.doc);
+ return this.props.treeView.doc.treeViewOpenIsTransient || Doc.IsDataProto(this.doc);
}
set treeViewOpen(c: boolean) {
if (this.treeViewOpenIsTransient) this._transientOpenState = c;
@@ -221,7 +221,7 @@ export class TreeView extends React.Component<TreeViewProps> {
} else {
// choose an appropriate embedding or make one. --- choose the first embedding that (1) user owns, (2) has no context field ... otherwise make a new embedding
const bestEmbedding =
- docView.props.Document.author === Doc.CurrentUserEmail && !Doc.IsDocDataProto(docView.props.Document)
+ docView.props.Document.author === Doc.CurrentUserEmail && !Doc.IsDataProto(docView.props.Document)
? docView.props.Document
: DocListCast(this.props.document.proto_embeddings).find(doc => !doc.embedContainer && doc.author === Doc.CurrentUserEmail);
const nextBestEmbedding = DocListCast(this.props.document.proto_embeddings).find(doc => doc.author === Doc.CurrentUserEmail);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5ac444147..95046661e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -483,7 +483,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return false;
}
- @undoBatch
@action
updateClusters(_freeform_useClusters: boolean) {
this.props.Document._freeform_useClusters = _freeform_useClusters;
@@ -534,7 +533,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
}
- @undoBatch
@action
updateCluster(doc: Doc) {
const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 47d7801e6..641088675 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -102,7 +102,6 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this._lassoPts = [];
};
- @undoBatch
@action
onKeyPress = (e: KeyboardEvent) => {
//make textbox and add it to this collection
@@ -111,7 +110,6 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const [x, y] = this.Transform.transformPoint(this._downX, this._downY);
if (e.key === '?') {
cm.setDefaultItem('?', (str: string) => this.props.addDocTab(Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _width: 400, x, y, _height: 512, _nativeWidth: 850, title: 'bing', data_useCors: true }), OpenWhere.addRight));
-
cm.displayMenu(this._downX, this._downY, undefined, true);
e.stopPropagation();
} else if (e.key === 'u' && this.props.ungroup) {
@@ -173,7 +171,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
e.stopPropagation();
} else if (!e.ctrlKey && !e.metaKey && SelectionManager.Views().length < 2) {
FormattedTextBox.SelectOnLoadChar = Doc.UserDoc().defaultTextLayout && !this.props.childLayoutString ? e.key : '';
- FormattedTextBox.LiveTextUndo = UndoManager.StartBatch('live text batch');
+ FormattedTextBox.LiveTextUndo = UndoManager.StartBatch('type new note');
this.props.addLiveTextDocument(DocUtils.GetNewTextDoc('-typed text-', x, y, 200, 100, this.props.xPadding === 0));
e.stopPropagation();
}
@@ -396,6 +394,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
return newCollection;
});
+ @undoBatch
@action
pileup = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const selected = this.marqueeSelect(false);
@@ -508,8 +507,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
};
@undoBatch
- @action
- summary = (e: KeyboardEvent | React.PointerEvent | undefined) => {
+ summary = action((e: KeyboardEvent | React.PointerEvent | undefined) => {
const selected = this.marqueeSelect(false).map(d => {
this.props.removeDocument?.(d);
d.x = NumCast(d.x) - this.Bounds.left;
@@ -534,19 +532,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.props.addDocument?.(portal);
this.props.addLiveTextDocument(summary);
MarqueeOptionsMenu.Instance.fadeOut(true);
- };
+ });
@action
- background = (e: KeyboardEvent | React.PointerEvent | undefined) => {
- const newCollection = this.getCollection([], undefined, undefined);
- this.props.addDocument?.(newCollection);
- MarqueeOptionsMenu.Instance.fadeOut(true);
- this.hideMarquee();
- setTimeout(() => this.props.selectDocuments([newCollection]));
- };
-
- @undoBatch
- marqueeCommand = action((e: KeyboardEvent) => {
+ marqueeCommand = (e: KeyboardEvent) => {
if (this._commandExecuted || (e as any).propagationIsStopped) {
return;
}
@@ -557,7 +546,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.delete(e, e.key === 'h');
e.stopPropagation();
}
- if ('cbtsSpg'.indexOf(e.key) !== -1) {
+ if ('ctsSpg'.indexOf(e.key) !== -1) {
this._commandExecuted = true;
e.stopPropagation();
e.preventDefault();
@@ -565,7 +554,6 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
if (e.key === 'g') this.collection(e, true);
if (e.key === 'c' || e.key === 't') this.collection(e);
if (e.key === 's' || e.key === 'S') this.summary(e);
- if (e.key === 'b') this.background(e);
if (e.key === 'p') this.pileup(e);
this.cleanupInteractions(false);
}
@@ -575,7 +563,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
e.preventDefault();
this._lassoFreehand = !this._lassoFreehand;
}
- });
+ };
touchesLine(r1: { left: number; top: number; width: number; height: number }) {
for (const lassoPt of this._lassoPts) {
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index bcc2ca129..2a68f9b58 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -13,7 +13,7 @@ import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Docum
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
import { SelectionManager } from '../../../util/SelectionManager';
-import { undoBatch } from '../../../util/UndoManager';
+import { undoable, undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
@@ -25,6 +25,8 @@ import { CollectionSubView } from '../CollectionSubView';
import './CollectionSchemaView.scss';
import { SchemaColumnHeader } from './SchemaColumnHeader';
import { SchemaRowBox } from './SchemaRowBox';
+import { faHeartPulse } from '@fortawesome/free-solid-svg-icons';
+import { faGalacticSenate } from '@fortawesome/free-brands-svg-icons';
export enum ColumnType {
Number,
@@ -224,7 +226,7 @@ export class CollectionSchemaView extends CollectionSubView() {
@undoBatch
@action
- setSort = (field: string | undefined, desc: boolean = false) => {
+ setColumnSort = (field: string | undefined, desc: boolean = false) => {
this.layoutDoc.sortField = field;
this.layoutDoc.sortDesc = desc;
};
@@ -484,24 +486,11 @@ export class CollectionSchemaView extends CollectionSubView() {
return false;
};
- @action
- addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
- if (!value && !forceEmptyNote) return false;
- const newDoc = Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true });
- FormattedTextBox.SelectOnLoad = newDoc[Id];
- FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
- return this.addRow(newDoc) || false;
- };
-
menuCallback = (x: number, y: number) => {
ContextMenu.Instance.clearItems();
- DocUtils.addDocumentCreatorMenuItems(doc => this.addRow(doc), this.addRow, x, y, true);
+ DocUtils.addDocumentCreatorMenuItems(this.addRow, this.addRow, x, y, true);
- ContextMenu.Instance.setDefaultItem('::', (name: string): void => {
- Doc.GetProto(this.props.Document)[name] = '';
- this.addRow(Docs.Create.TextDocument('', { title: name, _layout_autoHeight: true }));
- });
ContextMenu.Instance.displayMenu(x, y, undefined, true);
};
@@ -866,7 +855,7 @@ export class CollectionSchemaView extends CollectionSubView() {
columnWidths={this.displayColumnWidths}
sortField={this.sortField}
sortDesc={this.sortDesc}
- setSort={this.setSort}
+ setSort={this.setColumnSort}
rowHeight={this.rowHeightFunc}
removeColumn={this.removeColumn}
resizeColumn={this.startResize}
@@ -879,7 +868,14 @@ export class CollectionSchemaView extends CollectionSubView() {
{this._columnMenuIndex !== undefined && this.renderColumnMenu}
{this._filterColumnIndex !== undefined && this.renderFilterMenu}
<CollectionSchemaViewDocs schema={this} childDocs={this.sortedDocsFunc} rowHeight={this.rowHeightFunc} setRef={(ref: HTMLDivElement | null) => (this._tableContentRef = ref)} />
- <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} height={CollectionSchemaView._newNodeInputHeight} />
+ <EditableView
+ GetValue={returnEmptyString}
+ SetValue={undoable(value => (value ? this.addRow(Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true })) : false), 'add text doc')}
+ placeholder={"Type ':' for commands"}
+ contents={'+ New Node'}
+ menuCallback={this.menuCallback}
+ height={CollectionSchemaView._newNodeInputHeight}
+ />
</div>
{this.previewWidth > 0 && <div className="schema-preview-divider" style={{ width: CollectionSchemaView._previewDividerWidth }} onPointerDown={this.onDividerDown}></div>}
{this.previewWidth > 0 && (
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 7da3c042c..46c2f622b 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -5,8 +5,6 @@ import { observer } from 'mobx-react';
import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
import { Colors } from '../../global/globalEnums';
import './CollectionSchemaView.scss';
-import { SnappingManager } from '../../../util/SnappingManager';
-import { DragManager } from '../../../util/DragManager';
export interface SchemaColumnHeaderProps {
columnKeys: string[];
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 45bfe4f77..978b65053 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -7,7 +7,7 @@ import { Doc } from '../../../../fields/Doc';
import { BoolCast } from '../../../../fields/Types';
import { DragManager } from '../../../util/DragManager';
import { SnappingManager } from '../../../util/SnappingManager';
-import { undoBatch } from '../../../util/UndoManager';
+import { undoable, undoBatch } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { OpenWhere } from '../../nodes/DocumentView';
@@ -111,18 +111,18 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps>() {
}}>
<div
className="schema-row-button"
- onPointerDown={undoBatch(e => {
+ onPointerDown={undoable(e => {
e.stopPropagation();
this.props.removeDocument?.(this.rootDoc);
- })}>
+ }, 'Delete Row')}>
<FontAwesomeIcon icon="times" />
</div>
<div
className="schema-row-button"
- onPointerDown={e => {
+ onPointerDown={undoable(e => {
e.stopPropagation();
this.props.addDocTab(this.rootDoc, OpenWhere.addRight);
- }}>
+ }, 'Open Doc on Right')}>
<FontAwesomeIcon icon="external-link-alt" />
</div>
</div>
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 42bf32475..6d5ef9df6 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -122,7 +122,7 @@ export class SchemaTableCell extends React.Component<SchemaTableCellProps> {
const ret = KeyValueBox.SetField(this.props.Document, this.props.fieldKey.replace(/^_/, ''), value);
this.props.finishEdit?.();
return ret;
- })}
+ }, 'edit schema cell')}
/>
</div>
);