diff options
-rw-r--r-- | src/client/views/collections/CollectionMenu.tsx | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.scss | 5 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 148 | ||||
-rw-r--r-- | src/client/views/collections/SchemaTable.tsx | 6 | ||||
-rw-r--r-- | src/client/views/globalCssVariables.scss | 2 | ||||
-rw-r--r-- | src/client/views/globalCssVariables.scss.d.ts | 1 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 1 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextMenu.tsx | 4 | ||||
-rw-r--r-- | src/server/websocket.ts | 4 |
9 files changed, 63 insertions, 112 deletions
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 4bdb233c9..429764154 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -528,9 +528,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu return SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; } @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } - @computed get isText() { - return this.selectedDoc?.type === DocumentType.RTF || RichTextMenu.Instance?.view ? true : false; - } + @computed get isText() { return this.selectedDoc?.type === DocumentType.RTF || RichTextMenu.Instance?.view ? true : false; } @undoBatch @action diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index b0b5f995a..2bdd280ec 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -30,7 +30,7 @@ .collectionSchemaView-dividerDragger { position: relative; height: 100%; - width: 20px; + width: $SCHEMA_DIVIDER_WIDTH; z-index: 20; right: 0; top: 0; @@ -228,6 +228,9 @@ position: absolute; background: white; padding: 5px; + position: fixed; + background: white; + border: black 1px solid; .collectionSchema-header-toggler { z-index: 100; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 27575374a..889cc7b0d 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -11,12 +11,12 @@ import { listSpec } from "../../../fields/Schema"; import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; import { Cast, NumCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, returnFalse, returnOne, returnZero, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, returnFalse, returnOne, setupMoveUpEvents } from "../../../Utils"; import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; -import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss'; +import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss'; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import '../DocumentDecorations.scss'; @@ -47,24 +47,26 @@ const columnTypes: Map<string, ColumnType> = new Map([ @observer export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _previewCont?: HTMLDivElement; - private DIVIDER_WIDTH = 4; - - @observable previewDoc: Doc | undefined = undefined; - @observable private _focusedTable: Doc = this.props.Document; - - @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } - @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } - @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } - @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } + @observable _previewDoc: Doc | undefined = undefined; + @observable _focusedTable: Doc = this.props.Document; + @observable _col: any = ""; @observable _menuWidth = 0; @observable _headerOpen = false; @observable _headerIsEditing = false; - @observable _col: any = ""; @observable _menuHeight = 0; @observable _pointerX = 0; @observable _pointerY = 0; @observable _openTypes: boolean = false; + + @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } + @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } + @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - Number(SCHEMA_DIVIDER_WIDTH) - this.previewWidth(); } + @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } + @computed get scale() { return this.props.ScreenToLocalTransform().Scale; } + @computed get columns() { return Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []); } + set columns(columns: SchemaHeaderField[]) { this.props.Document._schemaHeaders = new List<SchemaHeaderField>(columns); } + @computed get menuCoordinates() { let searchx = 0; let searchy = 0; @@ -81,15 +83,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return this.props.ScreenToLocalTransform().transformPoint(x, y); } - @computed get scale() { return this.props.ScreenToLocalTransform().Scale; } - - @computed get columns() { - return Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []); - } - set columns(columns: SchemaHeaderField[]) { - this.props.Document._schemaHeaders = new List<SchemaHeaderField>(columns); - } - get documentKeys() { const docs = this.childDocs; const keys: { [key: string]: boolean } = {}; @@ -104,27 +97,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this.columns.forEach(key => keys[key.heading] = true); return Array.from(Object.keys(keys)); } - @computed get possibleKeys() { return this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1); } @action setHeaderIsEditing = (isEditing: boolean) => this._headerIsEditing = isEditing; - - @action - changeColumnType = (type: ColumnType, col: any): void => { - this._openTypes = false; - this.setColumnType(col, type); - } - - changeColumnSort = (desc: boolean | undefined, col: any): void => { - this.setColumnSort(col, desc); - } - - changeColumnColor = (color: string, col: any): void => { - this.setColumnColor(col, color); - } - @undoBatch setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => { + this._openTypes = false; if (columnTypes.get(columnField.heading)) return; const columns = this.columns; @@ -165,42 +143,42 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { const type = col.type; - const anyType = <div className={"columnMenu-option" + (type === ColumnType.Any ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.Any, col)}> + const anyType = <div className={"columnMenu-option" + (type === ColumnType.Any ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Any)}> <FontAwesomeIcon icon={"align-justify"} size="sm" /> Any </div>; - const numType = <div className={"columnMenu-option" + (type === ColumnType.Number ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.Number, col)}> + const numType = <div className={"columnMenu-option" + (type === ColumnType.Number ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Number)}> <FontAwesomeIcon icon={"hashtag"} size="sm" /> Number </div>; - const textType = <div className={"columnMenu-option" + (type === ColumnType.String ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.String, col)}> + const textType = <div className={"columnMenu-option" + (type === ColumnType.String ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.String)}> <FontAwesomeIcon icon={"font"} size="sm" /> Text </div>; - const boolType = <div className={"columnMenu-option" + (type === ColumnType.Boolean ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.Boolean, col)}> + const boolType = <div className={"columnMenu-option" + (type === ColumnType.Boolean ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Boolean)}> <FontAwesomeIcon icon={"check-square"} size="sm" /> Checkbox </div>; - const listType = <div className={"columnMenu-option" + (type === ColumnType.List ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.List, col)}> + const listType = <div className={"columnMenu-option" + (type === ColumnType.List ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.List)}> <FontAwesomeIcon icon={"list-ul"} size="sm" /> List </div>; - const docType = <div className={"columnMenu-option" + (type === ColumnType.Doc ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.Doc, col)}> + const docType = <div className={"columnMenu-option" + (type === ColumnType.Doc ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Doc)}> <FontAwesomeIcon icon={"file"} size="sm" /> Document </div>; - const imageType = <div className={"columnMenu-option" + (type === ColumnType.Image ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.Image, col)}> + const imageType = <div className={"columnMenu-option" + (type === ColumnType.Image ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Image)}> <FontAwesomeIcon icon={"image"} size="sm" /> Image </div>; - const dateType = <div className={"columnMenu-option" + (type === ColumnType.Date ? " active" : "")} onClick={() => this.changeColumnType(ColumnType.Date, col)}> + const dateType = <div className={"columnMenu-option" + (type === ColumnType.Date ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Date)}> <FontAwesomeIcon icon={"calendar"} size="sm" /> Date </div>; @@ -239,15 +217,15 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { <div className="collectionSchema-headerMenu-group"> <label>Sort by:</label> <div className="columnMenu-sort"> - <div className={"columnMenu-option" + (sort === true ? " active" : "")} onClick={() => this.changeColumnSort(true, col)}> + <div className={"columnMenu-option" + (sort === true ? " active" : "")} onClick={() => this.setColumnSort(col, true)}> <FontAwesomeIcon icon="sort-amount-down" size="sm" /> Sort descending </div> - <div className={"columnMenu-option" + (sort === false ? " active" : "")} onClick={() => this.changeColumnSort(false, col)}> + <div className={"columnMenu-option" + (sort === false ? " active" : "")} onClick={() => this.setColumnSort(col, false)}> <FontAwesomeIcon icon="sort-amount-up" size="sm" /> Sort ascending </div> - <div className="columnMenu-option" onClick={() => this.changeColumnSort(undefined, col)}> + <div className="columnMenu-option" onClick={() => this.setColumnSort(col, undefined)}> <FontAwesomeIcon icon="times" size="sm" /> Clear sorting </div> @@ -270,12 +248,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { <div className="collectionSchema-headerMenu-group"> <label>Color:</label> <div className="columnMenu-colors"> - <div className={"columnMenu-colorPicker" + (selected === pink ? " active" : "")} style={{ backgroundColor: pink }} onClick={() => this.changeColumnColor(pink!, col)}></div> - <div className={"columnMenu-colorPicker" + (selected === purple ? " active" : "")} style={{ backgroundColor: purple }} onClick={() => this.changeColumnColor(purple!, col)}></div> - <div className={"columnMenu-colorPicker" + (selected === blue ? " active" : "")} style={{ backgroundColor: blue }} onClick={() => this.changeColumnColor(blue!, col)}></div> - <div className={"columnMenu-colorPicker" + (selected === yellow ? " active" : "")} style={{ backgroundColor: yellow }} onClick={() => this.changeColumnColor(yellow!, col)}></div> - <div className={"columnMenu-colorPicker" + (selected === red ? " active" : "")} style={{ backgroundColor: red }} onClick={() => this.changeColumnColor(red!, col)}></div> - <div className={"columnMenu-colorPicker" + (selected === gray ? " active" : "")} style={{ backgroundColor: gray }} onClick={() => this.changeColumnColor(gray, col)}></div> + <div className={"columnMenu-colorPicker" + (selected === pink ? " active" : "")} style={{ backgroundColor: pink }} onClick={() => this.setColumnColor(col, pink!)}></div> + <div className={"columnMenu-colorPicker" + (selected === purple ? " active" : "")} style={{ backgroundColor: purple }} onClick={() => this.setColumnColor(col, purple!)}></div> + <div className={"columnMenu-colorPicker" + (selected === blue ? " active" : "")} style={{ backgroundColor: blue }} onClick={() => this.setColumnColor(col, blue!)}></div> + <div className={"columnMenu-colorPicker" + (selected === yellow ? " active" : "")} style={{ backgroundColor: yellow }} onClick={() => this.setColumnColor(col, yellow!)}></div> + <div className={"columnMenu-colorPicker" + (selected === red ? " active" : "")} style={{ backgroundColor: red }} onClick={() => this.setColumnColor(col, red!)}></div> + <div className={"columnMenu-colorPicker" + (selected === gray ? " active" : "")} style={{ backgroundColor: gray }} onClick={() => this.setColumnColor(col, gray)}></div> </div> </div> ); @@ -320,8 +298,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action closeHeader = () => { this._headerOpen = false; } - - @undoBatch @action deleteColumn = (key: string) => { @@ -351,15 +327,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { onWheel(e: React.WheelEvent) { const scale = this.props.ScreenToLocalTransform().Scale; this.props.active(true) && e.stopPropagation(); - //this.menuCoordinates[0] -= e.screenX / scale; - //this.menuCoordinates[1] -= e.screenY / scale; } @computed get renderMenuContent() { TraceMobx(); return <div className="collectionSchema-header-menuOptions"> {this.renderTypes(this._col)} - {/* {this.renderSorting(this._col)} */} {this.renderColors(this._col)} <div className="collectionSchema-headerMenu-group"> <button onClick={() => { this.deleteColumn(this._col.heading); }} @@ -379,7 +352,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action setPreviewDoc = (doc: Opt<Doc>) => { SelectionManager.SelectSchemaDoc(this, doc); - this.previewDoc = doc; + this._previewDoc = doc; } //toggles preview side-panel of schema @@ -389,7 +362,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } onDividerDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.onDividerMove, emptyFunction, action(() => this.toggleExpander())); + setupMoveUpEvents(this, e, this.onDividerMove, emptyFunction, this.toggleExpander); } @action onDividerMove = (e: PointerEvent, down: number[], delta: number[]) => { @@ -405,21 +378,19 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { onPointerDown = (e: React.PointerEvent): void => { if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { if (this.props.isSelected(true)) e.stopPropagation(); - else { - this.props.select(false); - } + else this.props.select(false); } } @computed - get previewDocument(): Doc | undefined { return this.previewDoc; } + get previewDocument(): Doc | undefined { return this._previewDoc; } @computed get dividerDragger() { return this.previewWidth() === 0 ? (null) : - <div className="collectionSchemaView-dividerDragger" - onPointerDown={this.onDividerDown} - style={{ width: `${this.DIVIDER_WIDTH}px` }} />; + <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} > + <div className="collectionSchemaView-dividerDragger" /> + </div>; } @computed @@ -501,18 +472,19 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return <div className="collectionSchemaView-toolbar"> <div className="collectionSchemaView-toolbar-item"> <div id="preview-schema-checkbox-div"> - <input type="checkbox" - key={"Show Preview"} checked={this.previewWidth() !== 0} - onChange={this.toggleExpander} />Show Preview</div> + <input type="checkbox" key={"Show Preview"} checked={this.previewWidth() !== 0} onChange={this.toggleExpander} /> + Show Preview + </div> </div> </div>; } + onSpecificMenu = (e: React.MouseEvent) => { if ((e.target as any)?.className?.includes?.("collectionSchemaView-cell") || (e.target instanceof HTMLSpanElement)) { const cm = ContextMenu.Instance; const options = cm.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; - optionItems.push({ description: "remove", event: () => this.previewDoc && this.props.removeDocument(this.previewDoc), icon: "trash" }); + optionItems.push({ description: "remove", event: () => this._previewDoc && this.props.removeDocument(this._previewDoc), icon: "trash" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); cm.displayMenu(e.clientX, e.clientY); (e.nativeEvent as any).SchemaHandled = true; // not sure why this is needed, but if you right-click quickly on a cell, the Document/Collection contextMenu handlers still fire without this. @@ -558,39 +530,16 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this.columns = columns; } - onZoomMenu = (e: React.WheelEvent) => { - this.props.active(true) && e.stopPropagation(); - if (this.menuCoordinates[0] > e.screenX) { - this.menuCoordinates[0] -= e.screenX; //* this.scale; - } else { - this.menuCoordinates[0] += e.screenX; //* this.scale; - } - if (this.menuCoordinates[1] > e.screenY) { - this.menuCoordinates[1] -= e.screenY; //* this.scale; - } else { - this.menuCoordinates[1] += e.screenY; //* this.scale; - } - } - - + onZoomMenu = (e: React.WheelEvent) => { this.props.active(true) && e.stopPropagation(); } - onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { - } render() { - let name = "collectionSchemaView-container"; - if (this.props.Document._searchDoc) { - name = "collectionSchemaView-searchContainer"; - } - if (!this.props.active()) setTimeout(() => this.closeHeader(), 0); TraceMobx(); + if (!this.props.active()) setTimeout(() => this.closeHeader(), 0); const menuContent = this.renderMenuContent; const menu = <div className="collectionSchema-header-menu" onWheel={e => this.onZoomMenu(e)} onPointerDown={e => this.onHeaderClick(e)} - style={{ - position: "fixed", background: "white", border: "black 1px solid", - transform: `translate(${(this.menuCoordinates[0])}px, ${(this.menuCoordinates[1])}px)` - }}> + style={{ transform: `translate(${(this.menuCoordinates[0])}px, ${(this.menuCoordinates[1])}px)` }}> <Measure offset onResize={action((r: any) => { const dim = this.props.ScreenToLocalTransform().inverse().transformDirection(r.offset.width, r.offset.height); this._menuWidth = dim[0]; this._menuHeight = dim[1]; @@ -598,7 +547,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { {({ measureRef }) => <div ref={measureRef}> {menuContent} </div>} </Measure> </div>; - return <div className={name} + return <div className={"collectionSchemaView" + (this.props.Document._searchDoc ? "-searchContainer" : "-container")} style={{ overflow: this.props.overflow === true ? "scroll" : undefined, backgroundColor: "white", pointerEvents: this.props.Document._searchDoc !== undefined && !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined, @@ -606,7 +555,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { }} > <div className="collectionSchemaView-tableContainer" style={{ width: `calc(100% - ${this.previewWidth()}px)` }} - onKeyPress={this.onKeyPress} onContextMenu={this.onSpecificMenu} onPointerDown={this.onPointerDown} onWheel={e => this.props.active(true) && e.stopPropagation()} diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index eda62bf0b..12827ff66 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -17,7 +17,7 @@ import { Docs, DocumentOptions } from "../../documents/Documents"; import { CompileScript, Transformer, ts } from "../../util/Scripting"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; -import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss'; +import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss'; import { ContextMenu } from "../ContextMenu"; import '../DocumentDecorations.scss'; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; @@ -90,8 +90,6 @@ export interface SchemaTableProps { @observer export class SchemaTable extends React.Component<SchemaTableProps> { - private DIVIDER_WIDTH = 4; - @observable _cellIsEditing: boolean = false; @observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 }; @observable _openCollections: Set<number> = new Set; @@ -104,7 +102,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> { @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } - @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } + @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - Number(SCHEMA_DIVIDER_WIDTH) - this.previewWidth(); } @computed get childDocs() { if (this.props.childDocs) return this.props.childDocs; diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index 1539d1399..1e0b023d7 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -34,6 +34,7 @@ $mainTextInput-zindex: 999; // then text input overlay so that it's context menu $docDecorations-zindex: 998; // then doc decorations appear over everything else $remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right? $COLLECTION_BORDER_WIDTH: 1; +$SCHEMA_DIVIDER_WIDTH: 4; $MINIMIZED_ICON_SIZE:25; $MAX_ROW_HEIGHT: 44px; $DFLT_IMAGE_NATIVE_DIM: 900px; @@ -41,6 +42,7 @@ $MENU_PANEL_WIDTH: 60px; :export { contextMenuZindex: $contextMenu-zindex; + SCHEMA_DIVIDER_WIDTH: $SCHEMA_DIVIDER_WIDTH; COLLECTION_BORDER_WIDTH: $COLLECTION_BORDER_WIDTH; MINIMIZED_ICON_SIZE: $MINIMIZED_ICON_SIZE; MAX_ROW_HEIGHT: $MAX_ROW_HEIGHT; diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/globalCssVariables.scss.d.ts index fb3a327d0..c56b75d5e 100644 --- a/src/client/views/globalCssVariables.scss.d.ts +++ b/src/client/views/globalCssVariables.scss.d.ts @@ -1,6 +1,7 @@ interface IGlobalScss { contextMenuZindex: string; // context menu shows up over everything + SCHEMA_DIVIDER_WIDTH: string; COLLECTION_BORDER_WIDTH: string; MINIMIZED_ICON_SIZE: string; MAX_ROW_HEIGHT: string; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index c6bd0cb81..a5bcf988a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1450,6 +1450,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static LiveTextUndo: UndoManager.Batch | undefined; public static HadSelection: boolean = false; onBlur = (e: any) => { + RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined); FormattedTextBox.HadSelection = window.getSelection()?.toString() !== ""; this.endUndoTypingBatch(); this.doLinkOnDeselect(); diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index d492b561b..2700c508b 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -153,11 +153,11 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { public delayHide = () => this._delayHide = true; @action - public updateMenu(view: EditorView, lastState: EditorState | undefined, props: any) { + public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any) { + this.view = view; if (!view || !view.hasFocus()) { return; } - this.view = view; props && (this.editorProps = props); // Don't do anything if the document/selection didn't change diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 459fa520b..c9b5d1cbf 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -276,7 +276,7 @@ export namespace WebSocket { const updatefield = Array.from(Object.keys(diff.diff.$set))[0]; const newListItems = diff.diff.$set[updatefield].fields; const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields || []; - diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => !curList.some((curItem: any) => curItem.fieldId === newItem.fieldId))]; + diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : false))]; const sendBack = true;//curList.length !== prelen; Database.Instance.update(diff.id, diff.diff, () => { @@ -294,7 +294,7 @@ export namespace WebSocket { const updatefield = Array.from(Object.keys(diff.diff.$set))[0]; const remListItems = diff.diff.$set[updatefield].fields; const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields || []; - diff.diff.$set[updatefield].fields = curList?.filter((curItem: any) => !remListItems.some((remItem: any) => remItem.fieldId === curItem.fieldId)); + diff.diff.$set[updatefield].fields = curList?.filter((curItem: any) => !remListItems.some((remItem: any) => remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : false)); const sendBack = true;//curList.length + remListItems.length !== prelen; Database.Instance.update(diff.id, diff.diff, () => { |