aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/formattedText/DashDocView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/formattedText/DashDocView.tsx')
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx120
1 files changed, 61 insertions, 59 deletions
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index c5167461b..7335c9286 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,18 +1,21 @@
-import { action, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { NodeSelection } from 'prosemirror-state';
+import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { Doc } from '../../../../fields/Doc';
import { Height, Width } from '../../../../fields/DocSymbols';
-import { NumCast, StrCast } from '../../../../fields/Types';
+import { NumCast } from '../../../../fields/Types';
import { emptyFunction, returnFalse, Utils } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { Docs, DocUtils } from '../../../documents/Documents';
import { Transform } from '../../../util/Transform';
-import { DocFocusOptions, DocumentView } from '../DocumentView';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { DocumentView } from '../DocumentView';
+import { FocusViewOptions } from '../FieldView';
import { FormattedTextBox } from './FormattedTextBox';
-import React = require('react');
+var horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
export class DashDocView {
dom: HTMLSpanElement; // container for label and value
root: any;
@@ -21,8 +24,7 @@ export class DashDocView {
this.dom = document.createElement('span');
this.dom.style.position = 'relative';
this.dom.style.textIndent = '0';
- this.dom.style.border = '1px solid ' + StrCast(tbox.layoutDoc.color, 'lightGray');
- this.dom.style.width = node.attrs.width;
+ this.dom.style.width = (+node.attrs.width.toString().replace('px', '') + horizPadding).toString();
this.dom.style.height = node.attrs.height;
this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block';
(this.dom.style as any).float = node.attrs.float;
@@ -62,7 +64,12 @@ export class DashDocView {
} catch {}
});
}
- selectNode() {}
+ deselectNode() {
+ this.dom.style.backgroundColor = '';
+ }
+ selectNode() {
+ this.dom.style.backgroundColor = 'rgb(141, 182, 247)';
+ }
}
interface IDashDocViewInternal {
@@ -78,27 +85,27 @@ interface IDashDocViewInternal {
getPos: any;
}
@observer
-export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
+export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewInternal> {
_spanRef = React.createRef<HTMLDivElement>();
_disposers: { [name: string]: IReactionDisposer } = {};
_textBox: FormattedTextBox;
- @observable _dashDoc: Doc | undefined;
- @observable _finalLayout: any;
- @observable _width: number = 0;
- @observable _height: number = 0;
+ @observable _dashDoc: Doc | undefined = undefined;
+ @computed get _width() {
+ return NumCast(this._dashDoc?._width);
+ }
+ @computed get _height() {
+ return NumCast(this._dashDoc?._height);
+ }
updateDoc = action((dashDoc: Doc) => {
this._dashDoc = dashDoc;
- this._finalLayout = dashDoc;
- if (this.props.width !== (this._dashDoc?._width ?? '') + 'px' || this.props.height !== (this._dashDoc?._height ?? '') + 'px') {
+ if (this._props.width !== (this._dashDoc?._width ?? '') + 'px' || this._props.height !== (this._dashDoc?._height ?? '') + 'px') {
try {
- this._width = NumCast(this._dashDoc?._width);
- this._height = NumCast(this._dashDoc?._height);
// bcz: an exception will be thrown if two embeddings are open at the same time when a doc view comment is made
- this.props.view.dispatch(
- this.props.view.state.tr.setNodeMarkup(this.props.getPos(), null, {
- ...this.props.node.attrs,
+ this._props.view.dispatch(
+ this._props.view.state.tr.setNodeMarkup(this._props.getPos(), null, {
+ ...this._props.node.attrs,
width: this._width + 'px',
height: this._height + 'px',
})
@@ -111,16 +118,17 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
constructor(props: IDashDocViewInternal) {
super(props);
- this._textBox = this.props.tbox;
+ makeObservable(this);
+ this._textBox = this._props.tbox;
- DocServer.GetRefField(this.props.docId + this.props.embedding).then(async dashDoc => {
+ DocServer.GetRefField(this._props.docId + this._props.embedding).then(async dashDoc => {
if (!(dashDoc instanceof Doc)) {
- this.props.embedding &&
- DocServer.GetRefField(this.props.docId).then(async dashDocBase => {
+ this._props.embedding &&
+ DocServer.GetRefField(this._props.docId).then(async dashDocBase => {
if (dashDocBase instanceof Doc) {
- const embedding = Doc.MakeEmbedding(dashDocBase, this.props.docId + this.props.embedding);
+ const embedding = Doc.MakeEmbedding(dashDocBase, this._props.docId + this._props.embedding);
embedding.layout_fieldKey = 'layout';
- this.props.fieldKey && DocUtils.makeCustomViewClicked(embedding, Docs.Create.StackingDocument, this.props.fieldKey, undefined);
+ this._props.fieldKey && DocUtils.makeCustomViewClicked(embedding, Docs.Create.StackingDocument, this._props.fieldKey, undefined);
this.updateDoc(embedding);
}
});
@@ -132,23 +140,18 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
componentDidMount() {
this._disposers.upater = reaction(
- () => this._dashDoc && NumCast(this._dashDoc._height) + NumCast(this._dashDoc._width),
- action(() => {
- if (this._dashDoc) {
- this._width = NumCast(this._dashDoc._width);
- this._height = NumCast(this._dashDoc._height);
- const parent = this._spanRef.current?.parentNode as HTMLElement;
- if (parent) {
- parent.style.width = this._width + 'px';
- parent.style.height = this._height + 'px';
- }
+ () => ({ width: this._width, height: this._height, parent: this._spanRef.current?.parentNode as HTMLElement }),
+ action(({ width, height, parent }) => {
+ if (parent) {
+ parent.style.width = width + 'px';
+ parent.style.height = height + 'px';
}
})
);
}
removeDoc = () => {
- this.props.view.dispatch(this.props.view.state.tr.setSelection(new NodeSelection(this.props.view.state.doc.resolve(this.props.getPos()))).deleteSelection());
+ this._props.view.dispatch(this._props.view.state.tr.setSelection(new NodeSelection(this._props.view.state.doc.resolve(this._props.getPos()))).deleteSelection());
return true;
};
@@ -157,7 +160,7 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
const { scale, translateX, translateY } = Utils.GetScreenTransform(this._spanRef.current);
return new Transform(-translateX, -translateY, 1).scale(1 / scale);
};
- outerFocus = (target: Doc, options: DocFocusOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target
+ outerFocus = (target: Doc, options: FocusViewOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target
onKeyDown = (e: any) => {
e.stopPropagation();
@@ -167,29 +170,30 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
};
onPointerLeave = () => {
- const ele = document.getElementById('DashDocCommentView-' + this.props.docId) as HTMLDivElement;
+ const ele = document.getElementById('DashDocCommentView-' + this._props.docId) as HTMLDivElement;
ele && (ele.style.backgroundColor = '');
};
onPointerEnter = () => {
- const ele = document.getElementById('DashDocCommentView-' + this.props.docId) as HTMLDivElement;
+ const ele = document.getElementById('DashDocCommentView-' + this._props.docId) as HTMLDivElement;
ele && (ele.style.backgroundColor = 'orange');
};
componentWillUnmount = () => Object.values(this._disposers).forEach(disposer => disposer?.());
+ isContentActive = () => this._props.tbox._props.isContentActive() || this._props.tbox.isAnyChildContentActive?.();
render() {
- return !this._dashDoc || !this._finalLayout || this.props.hidden ? null : (
+ return !this._dashDoc || this._props.hidden ? null : (
<div
ref={this._spanRef}
className="dash-span"
style={{
- width: this._width,
+ width: `calc(100% - ${horizPadding}px)`,
height: this._height,
- position: 'absolute',
- display: 'inline-block',
- left: 0,
- top: 0,
+ position: 'relative',
+ display: 'flex',
+ margin: 'auto',
+ pointerEvents: this.isContentActive() ? undefined : 'none',
}}
onPointerLeave={this.onPointerLeave}
onPointerEnter={this.onPointerEnter}
@@ -198,27 +202,25 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
onKeyUp={e => e.stopPropagation()}
onWheel={e => e.preventDefault()}>
<DocumentView
- Document={this._finalLayout}
+ Document={this._dashDoc}
addDocument={returnFalse}
- rootSelected={returnFalse} //{this._textBox.props.isSelected}
removeDocument={this.removeDoc}
isDocumentActive={returnFalse}
- isContentActive={emptyFunction}
- styleProvider={this._textBox.props.styleProvider}
- docViewPath={this._textBox.props.docViewPath}
+ isContentActive={this.isContentActive}
+ styleProvider={this._textBox._props.styleProvider}
+ containerViewPath={this._textBox.DocumentView?.().docViewPath}
ScreenToLocalTransform={this.getDocTransform}
- addDocTab={this._textBox.props.addDocTab}
+ addDocTab={this._textBox._props.addDocTab}
pinToPres={returnFalse}
- renderDepth={this._textBox.props.renderDepth + 1}
- PanelWidth={this._finalLayout[Width]}
- PanelHeight={this._finalLayout[Height]}
+ renderDepth={this._textBox._props.renderDepth + 1}
+ PanelWidth={this._dashDoc[Width]}
+ PanelHeight={this._dashDoc[Height]}
focus={this.outerFocus}
- whenChildContentsActiveChanged={returnFalse}
- bringToFront={emptyFunction}
+ whenChildContentsActiveChanged={this._props.tbox.whenChildContentsActiveChanged}
dontRegisterView={false}
- childFilters={this.props.tbox?.props.childFilters}
- childFiltersByRanges={this.props.tbox?.props.childFiltersByRanges}
- searchFilterDocs={this.props.tbox?.props.searchFilterDocs}
+ childFilters={this._props.tbox?._props.childFilters}
+ childFiltersByRanges={this._props.tbox?._props.childFiltersByRanges}
+ searchFilterDocs={this._props.tbox?._props.searchFilterDocs}
/>
</div>
);