From 7db0fe589afa3281894afb0a0d3bd6b9983c9d33 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 29 Mar 2021 19:04:08 -0400 Subject: still cleaning up all the active/selection code. --- src/fields/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/fields') diff --git a/src/fields/util.ts b/src/fields/util.ts index ea91cc057..6c9c9d45c 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -19,7 +19,7 @@ function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); } -const tracing = false; +const tracing = true; export function TraceMobx() { tracing && trace(); } -- cgit v1.2.3-70-g09d2 From 589f07ea018368057fe80b136c3fd2153efe0fcb Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 29 Mar 2021 20:36:47 -0400 Subject: fixed text input after changes to active/selected --- src/client/util/DragManager.ts | 7 +------ src/client/views/DocComponent.tsx | 4 ++-- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 4 +--- src/fields/util.ts | 2 +- 5 files changed, 6 insertions(+), 13 deletions(-) (limited to 'src/fields') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index abf1af669..c1235163b 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -379,12 +379,7 @@ export namespace DragManager { if (docsBeingDragged.length) { const pdfBox = dragElement.getElementsByTagName("canvas"); const pdfBoxSrc = ele.getElementsByTagName("canvas"); - Array.from(pdfBox).filter(pb => pb.width && pb.height).map((pb, i) => { - const context = pb.getContext('2d')!; - console.log(getComputedStyle(pb).width); - console.log(getComputedStyle(pdfBoxSrc[i]).width); - context.drawImage(pdfBoxSrc[i], 0, 0); - }); + Array.from(pdfBox).filter(pb => pb.width && pb.height).map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0)); } [dragElement, ...Array.from(dragElement.getElementsByTagName('*'))].forEach(ele => ele.hasAttribute("style") && ((ele as any).style.pointerEvents = "none")); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 5c0fe6b97..566e884c5 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -203,10 +203,10 @@ export function ViewBoxAnnotatableComponent

{ - this.props.layerProvider?.(doc, true); - Doc.AddDocToList(targetDataDoc, annotationKey ?? this.annotationKey, doc); doc.context = this.props.Document; if (annotationKey ?? this._annotationKey) Doc.GetProto(doc).annotationOn = this.props.Document; + this.props.layerProvider?.(doc, true); + Doc.AddDocToList(targetDataDoc, annotationKey ?? this.annotationKey, doc); }); } else { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b74bca5d3..cf48a9237 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1043,7 +1043,7 @@ export class CollectionFreeFormView extends CollectionSubView this.props.isContentActive()} + isDocumentActive={this.props.isContentActive} dontRegisterView={this.props.dontRegisterView} pointerEvents={this.backgroundActive || this.props.childPointerEvents ? "all" : (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : undefined} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 28e58f6d8..7787dc3a6 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1422,9 +1422,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const proseHeight = this.ProseRef?.scrollHeight || 0; const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight); if (scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation - const setScrollHeight = () => { - this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight; - }; + const setScrollHeight = () => this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight; if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) { setScrollHeight(); } else setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived... diff --git a/src/fields/util.ts b/src/fields/util.ts index 6c9c9d45c..ea91cc057 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -19,7 +19,7 @@ function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); } -const tracing = true; +const tracing = false; export function TraceMobx() { tracing && trace(); } -- cgit v1.2.3-70-g09d2 From 3a17df4daf6cd84afe8ee69b0f7b263f830566d7 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Wed, 31 Mar 2021 18:11:59 -0400 Subject: sharing bugfix + minor restructure + some comments --- src/client/util/CurrentUserUtils.ts | 1 + src/client/util/SharingManager.tsx | 77 +++++++++++++++++++------------------ src/fields/Doc.ts | 16 ++++++-- 3 files changed, 54 insertions(+), 40 deletions(-) (limited to 'src/fields') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 51bdd715b..257eb0aa2 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -911,6 +911,7 @@ export class CurrentUserUtils { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, _chromeHidden: true, }, sharingDocumentId + "outer", sharingDocumentId); + (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Add; } if (sharedDocs instanceof Doc) { sharedDocs.userColor = sharedDocs.userColor || "rgb(202, 202, 202)"; diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 2aea73528..ded56d1da 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -154,6 +154,26 @@ export class SharingManager extends React.Component<{}> { }); } } + /** + * Shares the document with a user. + */ + setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => { + const { user, sharingDoc } = recipient; + const target = targetDoc || this.targetDoc!; + const acl = `acl-${normalizeEmail(user.email)}`; + const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; + + const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); + + // ! ensures it returns true if document has been shared successfully, false otherwise + return !docs.map(doc => { + doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); + distributeAcls(acl, permission as SharingPermissions, doc); + + if (permission !== SharingPermissions.None) return Doc.AddDocToList(sharingDoc, storage, doc); + else return GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); + }).some(success => !success); + } /** * Sets the permission on the target for the group. @@ -168,7 +188,8 @@ export class SharingManager extends React.Component<{}> { const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); - docs.forEach(doc => { + // ! ensures it returns true if document has been shared successfully, false otherwise + return !docs.map(doc => { doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc); distributeAcls(acl, permission as SharingPermissions, doc); @@ -179,12 +200,12 @@ export class SharingManager extends React.Component<{}> { // if documents have been shared, add the doc to that list if it doesn't already exist, otherwise create a new list with the doc group.docsShared ? Doc.IndexOf(doc, DocListCast(group.docsShared)) === -1 && (group.docsShared as List).push(doc) : group.docsShared = new List([doc]); - users.forEach(({ user, sharingDoc }) => { - if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); // add the doc to the sharingDoc if it hasn't already been added - else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists - }); + return users.map(({ user, sharingDoc }) => { + if (permission !== SharingPermissions.None) return Doc.AddDocToList(sharingDoc, storage, doc); // add the doc to the sharingDoc if it hasn't already been added + else return GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists + }).some(success => !success); } - }); + }).some(success => success); } /** @@ -262,24 +283,6 @@ export class SharingManager extends React.Component<{}> { } } - /** - * Shares the document with a user. - */ - setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => { - const { user, sharingDoc } = recipient; - const target = targetDoc || this.targetDoc!; - const acl = `acl-${normalizeEmail(user.email)}`; - const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; - - const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); - docs.forEach(doc => { - doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); - distributeAcls(acl, permission as SharingPermissions, doc); - - if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); - else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); - }); - } // private setExternalSharing = (permission: string) => { @@ -313,11 +316,11 @@ export class SharingManager extends React.Component<{}> { if (!uniform) dropdownValues.unshift("-multiple-"); if (override) dropdownValues.unshift("None"); return dropdownValues.filter(permission => permission !== SharingPermissions.View).map(permission => - ( - - ) + ( + + ) ); } @@ -498,10 +501,10 @@ export class SharingManager extends React.Component<{}> { {this.sharingOptions(uniform)} ) : ( -

- {permissions === SharingPermissions.Add ? "Can Augment" : permissions} -
- )} +
+ {permissions === SharingPermissions.Add ? "Can Augment" : permissions} +
+ )} ); @@ -572,10 +575,10 @@ export class SharingManager extends React.Component<{}> { {this.sharingOptions(uniform, group.title === "Override")} ) : ( -
- {permissions} -
- )} +
+ {permissions} +
+ )} ); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index d0ccce9cf..5b3e21e34 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -429,6 +429,11 @@ export namespace Doc { index = allowProtos && index !== -1 ? index : list.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, toFind)) ? i : p, -1); return index; // list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind)); } + + /** + * Removes doc from the list of Docs at listDoc[fieldKey] + * @returns true if successful, false otherwise. + */ export function RemoveDocFromList(listDoc: Doc, fieldKey: string | undefined, doc: Doc) { const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc); if (listDoc[key] === undefined) { @@ -444,6 +449,11 @@ export namespace Doc { } return false; } + + /** + * Adds doc to the list of Docs stored at listDoc[fieldKey]. + * @returns true if successful, false otherwise. + */ export function AddDocToList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) { const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc); if (listDoc[key] === undefined) { @@ -477,9 +487,9 @@ export namespace Doc { return false; } - // - // Computes the bounds of the contents of a set of documents. - // + /** + * Computes the bounds of the contents of a set of documents. + */ export function ComputeContentBounds(docList: Doc[]) { const bounds = docList.reduce((bounds, doc) => { const [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)]; -- cgit v1.2.3-70-g09d2 From ec2748cf3deaa791c5aae6eae11b36f3cd4c0099 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 1 Apr 2021 10:40:25 -0400 Subject: cleaning up tree view stuff. --- src/client/documents/Documents.ts | 7 ++- .../views/collections/CollectionDockingView.tsx | 4 +- src/client/views/collections/TreeView.tsx | 51 +++++++++++----------- src/fields/documentSchemas.ts | 1 - 4 files changed, 30 insertions(+), 33 deletions(-) (limited to 'src/fields') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a37bedc8b..f02298f36 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -254,7 +254,6 @@ export class DocumentOptions { treeViewTruncateTitleWidth?: number; treeViewType?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy treeViewLockExpandedView?: boolean; // whether the expanded view can be changed - treeViewDefaultExpandedView?: string; // default expanded view sidebarColor?: string; // background color of text sidebar sidebarViewType?: string; // collection type of text sidebar docMaxAutoHeight?: number; // maximum height for newly created (eg, from pasting) text documents @@ -888,9 +887,9 @@ export namespace Docs { } export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { - const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", _fitWidth: true, system: true }); - const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true }); - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewDefaultExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); + const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewExpandedView: "data", _fitWidth: true, system: true }); + const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewLockExpandedView: true, treeViewExpandedView: "data", system: true }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); } export function DirectoryImportDocument(options: DocumentOptions = {}) { diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 52d3e91b9..388f9a909 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -437,9 +437,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { } render() { - return
- {this.props.renderDepth > 0 ? "Nested dashboards can't be rendered" : (null)} -
; + return
; } } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 71b4cf845..df851566f 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -94,13 +94,15 @@ export class TreeView extends React.Component { @observable _editTitle: boolean = false; @observable _dref: DocumentView | undefined | null; get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive - get treeViewLockExpandedView() { return this.doc.treeViewLockExpandedView; } - get defaultExpandedView() { return this.props.treeView.props.treeViewExpandedView || (StrCast(this.doc.treeViewDefaultExpandedView, this.props.treeView.fileSysMode ? (this.doc.isFolder ? "data" : "aliases") : Doc.UserDoc().noviceMode || this.props.treeView.outlineMode ? "layout" : "fields")); } - get treeViewDefaultExpandedView() { return this.treeViewLockExpandedView ? this.defaultExpandedView : (this.childDocs && !this.props.treeView.fileSysMode ? this.fieldKey : this.defaultExpandedView); } + get defaultExpandedView() { + return this.props.treeView.fileSysMode ? (this.doc.isFolder ? this.fieldKey : "aliases") : + this.props.treeView.outlineMode ? "layout" : + this.childDocs ? this.fieldKey : Doc.UserDoc().noviceMode ? "layout" : "fields"; + } @computed get doc() { return this.props.document; } @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && Doc.GetT(this.doc, "treeViewOpen", "boolean", true)) || this._overrideTreeViewOpen; } - @computed get treeViewExpandedView() { return StrCast(this.doc.treeViewExpandedView, this.treeViewDefaultExpandedView); } + @computed get treeViewExpandedView() { return StrCast(this.doc.treeViewExpandedView, this.defaultExpandedView); } @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containerCollection.maxEmbedHeight, 200); } @computed get dataDoc() { return this.doc[DataSym]; } @computed get layoutDoc() { return Doc.Layout(this.doc); } @@ -456,30 +458,29 @@ export class TreeView extends React.Component {
; } + @action + expandNextviewType = () => { + if (!this.doc.isFolder && !this.props.treeView.outlineMode && !this.doc.treeViewLockExpandedView) { + const next = (modes: any[]) => modes[(modes.indexOf(StrCast(this.doc.treeViewExpandedView)) + 1) % modes.length]; + const annos = () => DocListCast(this.doc[this.fieldKey + "-annotations"]).length ? "annotations" : ""; + const links = () => DocListCast(this.doc.links).length ? "links" : ""; + const children = () => this.childDocs ? this.fieldKey : ""; + this.doc.treeViewExpandedView = next(this.props.treeView.fileSysMode ? + (Doc.UserDoc().noviceMode ? ["layout", "aliases"] : ["layout", "aliases", "fields"]) : + (Doc.UserDoc().noviceMode ? [children(), "layout"] : [children(), "fields", "layout", links(), annos()]).filter(mode => mode)); + } + this.treeViewOpen = true; + } + @computed get headerElements() { - return this.props.treeViewHideHeaderFields() ? (null) - : Doc.IsSystem(this.doc) ? + return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null) + : <> { this.showContextMenu(e); e.stopPropagation(); }} /> - : <> - { this.showContextMenu(e); e.stopPropagation(); }} /> - { - if (this.props.treeView.fileSysMode) { - this.doc.treeViewExpandedView = this.doc.isFolder ? this.fieldKey : this.treeViewExpandedView === "layout" ? "aliases" : - this.treeViewExpandedView === "aliases" && !Doc.UserDoc().noviceMode ? "fields" : "layout"; - } else if (this.treeViewOpen) { - this.doc.treeViewExpandedView = this.treeViewLockExpandedView ? this.doc.treeViewExpandedView : - this.treeViewExpandedView === this.fieldKey ? (Doc.UserDoc().noviceMode || this.props.treeView.outlineMode ? "layout" : "fields") : - this.treeViewExpandedView === "fields" && this.layoutDoc ? "layout" : - this.treeViewExpandedView === "layout" && DocListCast(this.doc.links).length ? "links" : - (this.treeViewExpandedView === "links" || this.treeViewExpandedView === "layout") && DocListCast(this.doc[this.fieldKey + "-annotations"]).length ? "annotations" : - this.childDocs ? this.fieldKey : (Doc.UserDoc().noviceMode || this.props.treeView.outlineMode ? "layout" : "fields"); - } - this.treeViewOpen = true; - })}> + {this.doc.treeViewLockExpandedView ? (null) : + {this.treeViewExpandedView} - - ; + } + ; } showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 275249840..bf415d7a0 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -76,7 +76,6 @@ export const documentSchema = createSchema({ treeViewOpen: "boolean", // flag denoting whether the documents sub-tree (contents) is visible or hidden treeViewExpandedView: "string", // name of field whose contents are being displayed as the document's subtree treeViewLockExpandedView: "boolean", // whether the expanded view can be changed - treeViewDefaultExpandedView: "string", // name of field whose contents are displayed by default treeViewPreventOpen: "boolean", // ignores the treeViewOpen flag (for allowing a view to not be slaved to other views of the document) treeViewType: "string", // whether tree view is an outline, file syste or (default) hierarchy. For outline, clicks edit document titles immediately since double-click opening is turned off -- cgit v1.2.3-70-g09d2 From 7125bf2c1138637c9753b565b0690bb0fb5d93d0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 1 Apr 2021 11:45:56 -0400 Subject: more tree view cleanup --- src/client/documents/Documents.ts | 8 +++---- src/client/views/collections/TreeView.tsx | 38 ++++++++++++++++--------------- src/client/views/nodes/DocumentView.tsx | 16 ++++++------- src/client/views/nodes/FilterBox.tsx | 2 +- src/fields/documentSchemas.ts | 2 +- 5 files changed, 33 insertions(+), 33 deletions(-) (limited to 'src/fields') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f02298f36..404772b9d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -250,10 +250,10 @@ export class DocumentOptions { treeViewShowClearButton?: boolean; // whether a clear button should be displayed treeViewOpen?: boolean; // whether this document is expanded in a tree view treeViewExpandedView?: string; // which field/thing is displayed when this item is opened in tree view + treeViewExpandedViewLock?: boolean; // whether the expanded view can be changed treeViewChecked?: ScriptField; // script to call when a tree view checkbox is checked treeViewTruncateTitleWidth?: number; treeViewType?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy - treeViewLockExpandedView?: boolean; // whether the expanded view can be changed sidebarColor?: string; // background color of text sidebar sidebarViewType?: string; // collection type of text sidebar docMaxAutoHeight?: number; // maximum height for newly created (eg, from pasting) text documents @@ -887,9 +887,9 @@ export namespace Docs { } export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { - const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewExpandedView: "data", _fitWidth: true, system: true }); - const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewLockExpandedView: true, treeViewExpandedView: "data", system: true }); - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); + const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true }); + const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); } export function DirectoryImportDocument(options: DocumentOptions = {}) { diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index df851566f..d9ecc7083 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -96,8 +96,7 @@ export class TreeView extends React.Component { get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive get defaultExpandedView() { return this.props.treeView.fileSysMode ? (this.doc.isFolder ? this.fieldKey : "aliases") : - this.props.treeView.outlineMode ? "layout" : - this.childDocs ? this.fieldKey : Doc.UserDoc().noviceMode ? "layout" : "fields"; + this.props.treeView.outlineMode || this.childDocs ? this.fieldKey : Doc.UserDoc().noviceMode ? "layout" : "fields"; } @computed get doc() { return this.props.document; } @@ -211,6 +210,7 @@ export class TreeView extends React.Component { const bullet = Docs.Create.TextDocument("-text-", { layout: CollectionView.LayoutString("data"), title: "-title-", "sidebarColor": "transparent", "sidebarViewType": CollectionViewType.Freeform, + treeViewExpandedViewLock: true, treeViewExpandedView: "data", _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewType: "outline", x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, backgroundColor: "transparent", _width: 1000, _height: 10 }); @@ -460,7 +460,7 @@ export class TreeView extends React.Component { @action expandNextviewType = () => { - if (!this.doc.isFolder && !this.props.treeView.outlineMode && !this.doc.treeViewLockExpandedView) { + if (this.treeViewOpen && !this.doc.isFolder && !this.props.treeView.outlineMode && !this.doc.treeViewExpandedViewLock) { const next = (modes: any[]) => modes[(modes.indexOf(StrCast(this.doc.treeViewExpandedView)) + 1) % modes.length]; const annos = () => DocListCast(this.doc[this.fieldKey + "-annotations"]).length ? "annotations" : ""; const links = () => DocListCast(this.doc.links).length ? "links" : ""; @@ -476,7 +476,7 @@ export class TreeView extends React.Component { return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null) : <> { this.showContextMenu(e); e.stopPropagation(); }} /> - {this.doc.treeViewLockExpandedView ? (null) : + {this.doc.treeViewExpandedViewLock ? (null) : {this.treeViewExpandedView} } @@ -484,11 +484,11 @@ export class TreeView extends React.Component { } showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); - contextMenuItems = () => this.doc.isFolder ? - [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : Doc.IsSystem(this.doc) ? [] : - this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ? - [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }] : - [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }] + contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : this.doc.isFolder ? + [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : + this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ? + [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }] : + [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }] onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); @@ -600,7 +600,7 @@ export class TreeView extends React.Component { focus={this.refocus} whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} bringToFront={emptyFunction} - cantBrush={this.props.treeView.props.cantBrush} + disableDocBrushing={this.props.treeView.props.disableDocBrushing} hideLinkButton={BoolCast(this.props.treeView.props.Document.childHideLinkButton)} dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews, this.props.dontRegisterView)} docFilters={returnEmptyFilter} @@ -641,13 +641,6 @@ export class TreeView extends React.Component { ; } - // renders the text version of a document as the header (e.g., useful for Slide views where the "") - @computed get renderTitleAsHeader() { - return <> - {this.renderBullet} - {this.renderTitle} - ; - } renderEmbeddedDocument = (asText: boolean) => { const layout = StrCast(Doc.LayoutField(this.layoutDoc)); @@ -688,11 +681,20 @@ export class TreeView extends React.Component { whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} addDocTab={this.props.addDocTab} pinToPres={this.props.treeView.props.pinToPres} - cantBrush={this.props.treeView.props.cantBrush} + disableDocBrushing={this.props.treeView.props.disableDocBrushing} bringToFront={returnFalse} />; } + // renders the text version of a document as the header. This is used in the file system mode and in other vanilla tree views. + @computed get renderTitleAsHeader() { + return <> + {this.renderBullet} + {this.renderTitle} + ; + } + + // renders the document in the header field instead of a text proxy. @computed get renderDocumentAsHeader() { return <> {this.renderBullet} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5bf5b6e90..26cf52f17 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -121,7 +121,7 @@ export interface DocumentViewSharedProps { dontRegisterView?: boolean; hideLinkButton?: boolean; ignoreAutoHeight?: boolean; - cantBrush?: boolean; // whether the document doesn't show brush highlighting + disableDocBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over. pointerEvents?: string; scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document } @@ -438,16 +438,15 @@ export class DocumentViewInternal extends DocComponent this.onDoubleClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, scriptContext: this.props.scriptContext, thisContainer: this.props.ContainingCollectionDoc, documentView: this.props.DocumentView(), - clientX: e.clientX, - clientY: e.clientY, - shiftKey: e.shiftKey + clientX, clientY, shiftKey }, console.log); UndoManager.RunInBatch(() => func().result?.select === true ? this.props.select(false) : "", "on double click"); } else if (!Doc.IsSystem(this.rootDoc)) { @@ -458,15 +457,14 @@ export class DocumentViewInternal extends DocComponent this.onClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, scriptContext: this.props.scriptContext, thisContainer: this.props.ContainingCollectionDoc, documentView: this.props.DocumentView(), - clientX: e.clientX, - clientY: e.clientY, - shiftKey: e.shiftKey + clientX, clientY, shiftKey }, console.log).result?.select === true ? this.props.select(false) : ""; const clickFunc = () => this.props.Document.dontUndo ? func() : UndoManager.RunInBatch(func, "on click"); if (this.onDoubleClickHandler) { @@ -950,7 +948,7 @@ export class DocumentViewInternal extends DocComponent