diff options
-rw-r--r-- | src/client/documents/Documents.ts | 1 | ||||
-rw-r--r-- | src/client/util/DocumentManager.ts | 11 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaCells.tsx | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.scss | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 52 | ||||
-rw-r--r-- | src/client/views/nodes/DocuLinkBox.scss | 7 | ||||
-rw-r--r-- | src/client/views/nodes/DocuLinkBox.tsx | 11 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.scss | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 14 | ||||
-rw-r--r-- | src/server/authentication/models/current_user_utils.ts | 14 |
11 files changed, 95 insertions, 26 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 5f0e63b56..1f351e93f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -123,6 +123,7 @@ export interface DocumentOptions { displayTimecode?: number; // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) borderRounding?: string; boxShadow?: string; + dontRegisterChildren?: boolean; _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views schemaColumns?: List<SchemaHeaderField>; dockingConfig?: string; diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 323d31af2..6711947ad 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -92,10 +92,17 @@ export class DocumentManager { public getDocumentViews(toFind: Doc): DocumentView[] { const toReturn: DocumentView[] = []; + // heurstic to return the "best" documents first: + // choose an exact match over an alias match + // choose documents that have a PanelWidth() over those that don't (the treeview documents have no panelWidth) DocumentManager.Instance.DocumentViews.map(view => - view.props.Document.presBox === undefined && view.props.Document === toFind && toReturn.push(view)); + view.props.Document.presBox === undefined && view.props.PanelWidth() > 1 && view.props.Document === toFind && toReturn.push(view)); DocumentManager.Instance.DocumentViews.map(view => - view.props.Document.presBox === undefined && view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view)); + view.props.Document.presBox === undefined && view.props.PanelWidth() <= 1 && view.props.Document === toFind && toReturn.push(view)); + DocumentManager.Instance.DocumentViews.map(view => + view.props.Document.presBox === undefined && view.props.PanelWidth() > 1 && view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view)); + DocumentManager.Instance.DocumentViews.map(view => + view.props.Document.presBox === undefined && view.props.PanelWidth() <= 1 && view.props.Document !== toFind && Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view)); return toReturn; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index c98be0d4a..39d078a36 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -43,7 +43,7 @@ export type CloseCall = (toBeDeleted: DocumentView[]) => void; export class DocumentDecorations extends React.Component<{}, { value: string }> { static Instance: DocumentDecorations; private _resizeHdlId = ""; - private _keyinput: React.RefObject<HTMLInputElement>; + private _keyinput = React.createRef<HTMLInputElement>(); private _resizeBorderWidth = 16; private _linkBoxHeight = 20 + 3; // link button height + margin private _titleHeight = 20; @@ -62,7 +62,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> constructor(props: Readonly<{}>) { super(props); DocumentDecorations.Instance = this; - this._keyinput = React.createRef(); reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this.titleBlur(false)); } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index df7abad61..79b5d7bb7 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -77,7 +77,8 @@ export class CollectionSchemaCell extends React.Component<CellProps> { @action isEditingCallback = (isEditing: boolean): void => { - document.addEventListener("keydown", this.onKeyDown); + document.removeEventListener("keydown", this.onKeyDown); + isEditing && document.addEventListener("keydown", this.onKeyDown); this._isEditing = isEditing; this.props.setIsEditing(isEditing); this.props.changeFocusedCellByIndex(this.props.row, this.props.col); diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index 6ebe81545..fd4a963c3 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -123,6 +123,9 @@ .editableView-container-editing-oneLine { min-width: 15px; } + .documentView-node-topmost { + width: unset; + } } .treeViewItem-header-above { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index deff3d177..54ad2ad48 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -10,7 +10,7 @@ import { Document, listSpec } from '../../../new_fields/Schema'; import { ComputedField, ScriptField } from '../../../new_fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types'; import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; -import { emptyFunction, emptyPath, returnFalse, Utils } from '../../../Utils'; +import { emptyFunction, emptyPath, returnFalse, Utils, returnOne, returnZero, returnTransparent, returnTrue } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from "../../documents/DocumentTypes"; import { DocumentManager } from '../../util/DocumentManager'; @@ -34,6 +34,7 @@ import "./CollectionTreeView.scss"; import React = require("react"); import { CollectionViewType } from './CollectionView'; import { RichTextField } from '../../../new_fields/RichTextField'; +import { DocumentView } from '../nodes/DocumentView'; export interface TreeViewProps { @@ -92,6 +93,7 @@ class TreeView extends React.Component<TreeViewProps> { private _header?: React.RefObject<HTMLDivElement> = React.createRef(); private _treedropDisposer?: DragManager.DragDropDisposer; private _dref = React.createRef<HTMLDivElement>(); + private _tref = React.createRef<HTMLDivElement>(); get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive @@ -171,13 +173,16 @@ class TreeView extends React.Component<TreeViewProps> { editableView = (key: string, style?: string) => (<EditableView oneLine={true} display={"inline-block"} - editing={this.dataDoc[Id] === EditableView.loadId} + editing={true /*this.dataDoc[Id] === EditableView.loadId*/} contents={StrCast(this.props.document[key])} height={12} fontStyle={style} fontSize={12} GetValue={() => StrCast(this.props.document[key])} - SetValue={undoBatch((value: string) => Doc.SetInPlace(this.props.document, key, value, false) || true)} + SetValue={undoBatch((value: string) => { + Doc.SetInPlace(this.props.document, key, value, false) || true; + this.props.document.editTitle = undefined; + })} OnFillDown={undoBatch((value: string) => { Doc.SetInPlace(this.props.document, key, value, false); const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) }); @@ -263,6 +268,13 @@ class TreeView extends React.Component<TreeViewProps> { const finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0)); return finalXf; } + getTransform = () => { + const { scale, translateX, translateY } = Utils.GetScreenTransform(this._tref.current!); + const outerXf = this.props.outerXf(); + const offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); + const finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]); + return finalXf; + } docWidth = () => { const layoutDoc = Doc.Layout(this.props.document); const aspect = NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth); @@ -404,8 +416,8 @@ class TreeView extends React.Component<TreeViewProps> { */ @computed get renderTitle() { - const reference = React.createRef<HTMLDivElement>(); - const onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId[Id], true); + const onItemDown = SetupDrag(this._tref, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId[Id], true); + const editTitle = ScriptField.MakeFunction("this.editTitle=true", { this: Doc.name }); const headerElements = ( <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView} @@ -424,14 +436,40 @@ class TreeView extends React.Component<TreeViewProps> { <FontAwesomeIcon title="open in pane on right" icon="angle-right" size="lg" /> </div>); return <> - <div className="docContainer" title="click to edit title" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown} + <div className="docContainer" ref={this._tref} title="click to edit title" id={`docContainer-${this.props.parentKey}`} onPointerDown={onItemDown} style={{ background: Doc.IsHighlighted(this.props.document) ? "orange" : Doc.IsBrushed(this.props.document) ? "#06121212" : "0", fontWeight: this.props.document.searchMatch ? "bold" : undefined, outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined, pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none" }} > - {this.editableView("title")} + {this.props.document.editTitle ? + this.editableView("title") : + <DocumentView + Document={this.props.document} + DataDoc={undefined} + LibraryPath={this.props.libraryPath || []} + addDocument={undefined} + addDocTab={this.props.addDocTab} + pinToPres={emptyFunction} + onClick={editTitle} + moveDocument={this.props.moveDocument} + removeDocument={undefined} + ScreenToLocalTransform={this.getTransform} + ContentScaling={returnOne} + PanelWidth={returnZero} + PanelHeight={returnZero} + renderDepth={1} + focus={emptyFunction} + parentActive={returnTrue} + whenActiveChanged={emptyFunction} + bringToFront={emptyFunction} + dontRegisterView={BoolCast(this.props.treeViewId.dontRegisterChildren)} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + zoomToScale={emptyFunction} + getScale={returnOne} + />} </div > {this.props.treeViewHideHeaderFields() ? (null) : headerElements} {openRight} diff --git a/src/client/views/nodes/DocuLinkBox.scss b/src/client/views/nodes/DocuLinkBox.scss index 286033475..f2c203548 100644 --- a/src/client/views/nodes/DocuLinkBox.scss +++ b/src/client/views/nodes/DocuLinkBox.scss @@ -1,4 +1,4 @@ -.docuLinkBox-cont { +.docuLinkBox-cont, .docuLinkBox-cont-small { cursor: default; position: absolute; width: 15; @@ -21,4 +21,9 @@ padding-left: 2px; padding-top: 1px; } +} + +.docuLinkBox-cont-small { + width:5px; + height:5px; }
\ No newline at end of file diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx index 882e57006..776d2019d 100644 --- a/src/client/views/nodes/DocuLinkBox.tsx +++ b/src/client/views/nodes/DocuLinkBox.tsx @@ -124,8 +124,8 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc } render() { - const x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100); - const y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100); + const x = this.props.PanelWidth() > 1 ? NumCast(this.props.Document[this.props.fieldKey + "_x"], 100) : 0; + const y = this.props.PanelWidth() > 1 ? NumCast(this.props.Document[this.props.fieldKey + "_y"], 100) : 0; const c = StrCast(this.props.Document.backgroundColor, "lightblue"); const anchor = this.props.fieldKey === "anchor1" ? "anchor2" : "anchor1"; const anchorScale = (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : .15; @@ -140,9 +140,12 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc </div>} </div> ); - return <div className="docuLinkBox-cont" onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu} + const small = this.props.PanelWidth() <= 1; + return <div className={`docuLinkBox-cont${small ? "-small" : ""}`} onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu} ref={this._ref} style={{ - background: c, left: `calc(${x}% - 7.5px)`, top: `calc(${y}% - 7.5px)`, + background: c, + left: !small ? `calc(${x}% - 7.5px)` : undefined, + top: !small ? `calc(${y}% - 7.5px)` : undefined, transform: `scale(${anchorScale / this.props.ContentScaling()})` }} > {!this._editing && !this._forceOpen ? (null) : diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 56e3eb220..d1d96f0a1 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -5,6 +5,8 @@ position: inherit; top: 0; left: 0; + width: 100%; + height: 100%; border-radius: inherit; transition: outline .3s linear; cursor: grab; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7d2940df5..463c6b5bd 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1018,6 +1018,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu @computed get innards() { TraceMobx(); + if (!this.props.PanelWidth()) { + return <div style={{ display: "flex" }}> + {StrCast(this.props.Document.title)} + {this.Document.links && DocListCast(this.Document.links).filter(d => !d.hidden).filter(this.isNonTemporalLink).map((d, i) => + <div className="documentView-docuLinkWrapper" style={{ position: "absolute", top: 0, left: 0 }} key={`${d[Id]}`}> + <DocumentView {...this.props} ContentScaling={returnOne} ContainingCollectionDoc={this.props.Document} + PanelWidth={returnOne} PanelHeight={returnOne} Document={d} layoutKey={this.linkEndpoint(d)} backgroundColor={returnTransparent} removeDocument={undoBatch(doc => doc.hidden = true)} /> + </div>)} + </div>; + } const showTitle = StrCast(this.layoutDoc._showTitle); const showTitleHover = StrCast(this.layoutDoc._showTitleHover); const showCaption = StrCast(this.layoutDoc._showCaption); @@ -1116,8 +1126,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined, boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined, background: finalColor, - width: "100%", - height: "100%", opacity: this.Document.opacity }}> {this.Document.isBackground ? <div className="documentView-lock"> <FontAwesomeIcon icon="unlock" size="lg" /> </div> : (null)} @@ -1131,7 +1139,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } } -Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string="layout") { +Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string = "layout") { const dv = DocumentManager.Instance.getDocumentView(doc); if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(otherKey !== "layout", otherKey.replace("layout_", "")); else dv?.switchViews(true, layoutKey.replace("layout_", "")); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index f672da085..5d93f208a 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -37,17 +37,19 @@ export class CurrentUserUtils { @observable public static GuestMobile: Doc | undefined; static setupDefaultDocTemplates(doc: Doc, buttons?: string[]) { - const taskStatusValues = [ { title: "todo", _backgroundColor: "blue", color: "white" }, - { title: "in progress", _backgroundColor: "yellow", color: "black" }, - { title: "completed", _backgroundColor: "green", color: "white" } + const taskStatusValues = [{ title: "todo", _backgroundColor: "blue", color: "white" }, + { title: "in progress", _backgroundColor: "yellow", color: "black" }, + { title: "completed", _backgroundColor: "green", color: "white" } ]; const noteTemplates = [ Docs.Create.TextDocument("", { title: "text", style: "Note", isTemplateDoc: true, backgroundColor: "yellow" }), Docs.Create.TextDocument("", { title: "text", style: "Idea", isTemplateDoc: true, backgroundColor: "pink" }), Docs.Create.TextDocument("", { title: "text", style: "Topic", isTemplateDoc: true, backgroundColor: "lightBlue" }), Docs.Create.TextDocument("", { title: "text", style: "Person", isTemplateDoc: true, backgroundColor: "lightGreen" }), - Docs.Create.TextDocument("", { title: "text", style: "Todo", isTemplateDoc: true, backgroundColor: "orange",_autoHeight: false, - layout:FormattedTextBox.LayoutString("Todo"), _height: 100, _showCaption: "caption",caption: RichTextField.DashField("taskStatus") }) + Docs.Create.TextDocument("", { + title: "text", style: "Todo", isTemplateDoc: true, backgroundColor: "orange", _autoHeight: false, + layout: FormattedTextBox.LayoutString("Todo"), _height: 100, _showCaption: "caption", caption: RichTextField.DashField("taskStatus") + }) ]; doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations" }); Doc.addFieldEnumerations(Doc.GetProto(noteTemplates[4]), "taskStatus", taskStatusValues); @@ -221,7 +223,7 @@ export class CurrentUserUtils { _width: 50, _height: 25, title: "Library", fontSize: 10, letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: Docs.Create.TreeDocument([doc.workspaces as Doc, doc.documents as Doc, Docs.Prototypes.MainLinkDocument(), doc, doc.recentlyClosed as Doc], { - title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0", + title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0", dontRegisterChildren: true }), targetContainer: sidebarContainer, onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel;") |