diff options
Diffstat (limited to 'src/client/views/collections')
| -rw-r--r-- | src/client/views/collections/CollectionSchemaCells.tsx | 18 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionTreeView.scss | 1 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 46 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionView.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/collections/TreeView.tsx | 21 |
5 files changed, 48 insertions, 41 deletions
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 18ae260e8..2443bd34e 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -71,6 +71,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> { @observable protected _isEditing: boolean = false; protected _focusRef = React.createRef<HTMLDivElement>(); protected _rowDoc = this.props.rowProps.original; + protected _rowDataDoc = Doc.GetProto(this.props.rowProps.original); protected _dropDisposer?: DragManager.DragDropDisposer; @observable contents: string = ""; @@ -126,11 +127,11 @@ export class CollectionSchemaCell extends React.Component<CellProps> { private drop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.docDragData) { if (de.complete.docDragData.draggedDocuments.length === 1) { - this._rowDoc[this.renderFieldKey] = de.complete.docDragData.draggedDocuments[0]; + this._rowDataDoc[this.renderFieldKey] = de.complete.docDragData.draggedDocuments[0]; } else { const coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.complete.docDragData.draggedDocuments, {}); - this._rowDoc[this.renderFieldKey] = coll; + this._rowDataDoc[this.renderFieldKey] = coll; } e.stopPropagation(); } @@ -164,8 +165,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> { @computed get renderFieldKey() { return CollectionSchemaCell.resolvedFieldKey(this.props.rowProps.column.id!, this.props.rowProps.original); } onItemDown = async (e: React.PointerEvent) => { if (this.props.Document._searchDoc) { - const doc = Doc.GetProto(this._rowDoc); - const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc); + const aliasdoc = await SearchUtil.GetAliasesOfDocument(this._rowDataDoc); const targetContext = aliasdoc.length <= 0 ? undefined : Cast(aliasdoc[0].context, Doc, null); DocumentManager.Instance.jumpToDocument(this._rowDoc, false, () => undefined, targetContext); } @@ -238,10 +238,10 @@ export class CollectionSchemaCell extends React.Component<CellProps> { let retVal = false; if (value.startsWith(":=") || value.startsWith("=:=")) { const script = value.substring(value.startsWith("=:=") ? 3 : 2); - retVal = this.props.setComputed(script, value.startsWith(":=") ? Doc.GetProto(this.props.Document) : this.props.Document, this.renderFieldKey, this.props.row, this.props.col); + retVal = this.props.setComputed(script, value.startsWith(":=") ? this._rowDataDoc : this._rowDoc, this.renderFieldKey, this.props.row, this.props.col); } else { const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - script.compiled && (retVal = this.applyToDoc(this._rowDoc, this.props.row, this.props.col, script.run)); + script.compiled && (retVal = this.applyToDoc(this._rowDataDoc, this.props.row, this.props.col, script.run)); } if (retVal) { this._isEditing = false; // need to set this here. otherwise, the assignment of the field will invalidate & cause render() to be called with the wrong value for 'editing' @@ -251,10 +251,10 @@ export class CollectionSchemaCell extends React.Component<CellProps> { })} OnFillDown={async (value: string) => { const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - script.compiled && DocListCast(field). + script.compiled && DocListCast(this.props.Document[this.props.fieldKey]). forEach((doc, i) => value.startsWith(":=") ? - this.props.setComputed(value.substring(2), doc, this.renderFieldKey, i, this.props.col) : - this.applyToDoc(doc, i, this.props.col, script.run)); + this.props.setComputed(value.substring(2), Doc.GetProto(doc), this.renderFieldKey, i, this.props.col) : + this.applyToDoc(Doc.GetProto(doc), i, this.props.col, script.run)); }} /> : diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index 20bfc0e9d..c5add7cfb 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -28,6 +28,7 @@ .no-indent { padding-left: 0; + width: max-content; } .editableView-container { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index efbe5581b..257eaf7f0 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -41,7 +41,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll private _mainEle?: HTMLDivElement; public _uniqueId = Utils.GenerateGuid(); - @computed get doc() { return this.props.Document; } + @computed get doc() { TraceMobx(); return this.props.Document; } @computed get dataDoc() { return this.props.DataDoc || this.doc; } protected createTreeDropTarget = (ele: HTMLDivElement) => { @@ -82,7 +82,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll return true; } return false; - }) + }); @action addDoc = (doc: Doc | Doc[], relativeTo: Opt<Doc>, before?: boolean): boolean => { const doAddDoc = (doc: Doc | Doc[]) => @@ -117,7 +117,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {}); @computed get renderClearButton() { - return <div key="toolbar"> + return !this.doc.allowClear ? (null) : <div key="toolbar"> <button className="toolbar-button round-button" title="Empty" onClick={undoBatch(action(() => Doc.GetProto(this.doc)[this.props.fieldKey] = undefined))}> <FontAwesomeIcon icon={"trash"} size="sm" /> </button> @@ -192,37 +192,45 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); whenActiveChanged = (isActive: boolean) => { this.props.whenActiveChanged(this._isChildActive = isActive); }; active = (outsideReaction: boolean | undefined) => this.props.active(outsideReaction) || this._isChildActive; - render() { + @computed get treeChildren() { + TraceMobx(); + return this.props.overrideDocuments ? this.props.overrideDocuments : this.childDocs; + } + @computed get treeViewElements() { TraceMobx(); - if (!(this.doc instanceof Doc)) return (null); const dropAction = StrCast(this.doc.childDropAction) as dropActionType; const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before); const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(d, target, addDoc); - const childDocs = this.props.overrideDocuments ? this.props.overrideDocuments : this.childDocs; - const childElements = childDocs && TreeView.GetChildElements(childDocs, this, this.doc, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove, + return TreeView.GetChildElements(this.treeChildren, this, this.doc, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove, moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.outerXf, this.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick, this.onChildClick, this.props.ignoreFields, true, this.whenActiveChanged); + } + @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; - const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.doc.backgroundColor) || this.props.backgroundColor?.(this.doc, this.props.renderDepth); + return hideTitle ? (null) : (this.doc.treeViewOutlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren); + } + render() { + TraceMobx(); + if (!(this.doc instanceof Doc)) return (null); + const background = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.doc.backgroundColor) || this.props.backgroundColor?.(this.doc, this.props.renderDepth); + const paddingX = `${NumCast(this.doc._xPadding, 10)}px`; + const paddingTop = `${NumCast(this.doc._yPadding, 20)}px`; + const pointerEvents = !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined; - return !childDocs ? (null) : ( + return !this.treeChildren ? (null) : ( <div className="collectionTreeView-container" onContextMenu={this.onContextMenu}> <div className="collectionTreeView-dropTarget" - style={{ - background: backgroundColor, - paddingLeft: `${NumCast(this.doc._xPadding, 10)}px`, - paddingRight: `${NumCast(this.doc._xPadding, 10)}px`, - paddingTop: `${NumCast(this.doc._yPadding, 20)}px`, - pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined, - }} + style={{ background, paddingLeft: paddingX, paddingRight: paddingX, paddingTop, pointerEvents }} onWheel={(e) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> - {hideTitle ? (null) : (this.doc.treeViewOutlineMode ? this.documentTitle : this.editableTitle)(childDocs)} - {this.doc.allowClear ? this.renderClearButton : (null)} - <ul className="no-indent" style={{ width: "max-content" }} > {childElements} </ul> + {this.titleBar} + {this.renderClearButton} + <ul className="no-indent"> + {this.treeViewElements} + </ul> </div > </div> ); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index c9496d374..e35474b81 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -144,7 +144,8 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus added.forEach(d => { for (const [key, value] of Object.entries(this.props.Document[AclSym])) { if (d.author === key.substring(4).replace("_", ".") && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true); - else distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true); + else if (this.props.Document[key] === SharingPermissions.Admin) distributeAcls(key, SharingPermissions.Add, d, true); + //else distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true); } }); } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index edb703135..486e44f6b 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -83,9 +83,9 @@ export class TreeView extends React.Component<TreeViewProps> { private _uniqueId = Utils.GenerateGuid(); private _editMaxWidth: number | string = 0; - get doc() { return this.props.document; } + @computed get doc() { TraceMobx(); return this.props.document; } get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); } - get displayName() { return "TreeView(" + this.doc.title + ")"; } // this makes mobx trace() statements more descriptive + get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive get treeViewLockExpandedView() { return this.doc.treeViewLockExpandedView; } get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.noviceMode || this.outlineMode ? "layout" : "fields"); } get treeViewDefaultExpandedView() { return this.treeViewLockExpandedView ? this.defaultExpandedView : (this.childDocs ? this.fieldKey : this.defaultExpandedView); } @@ -100,14 +100,14 @@ export class TreeView extends React.Component<TreeViewProps> { @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); } @computed get dataDoc() { return this.doc[DataSym]; } @computed get layoutDoc() { return Doc.Layout(this.doc); } - @computed get fieldKey() { const splits = StrCast(Doc.LayoutField(this.doc)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; } + @computed get fieldKey() { TraceMobx(); const splits = StrCast(Doc.LayoutField(this.doc)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; } childDocList(field: string) { const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined; return ((this.props.dataDoc ? DocListCastOrNull(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field (layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields DocListCastOrNull(this.doc[field])); // otherwise use the document's data field } - @computed get childDocs() { return this.childDocList(this.fieldKey); } + @computed get childDocs() { TraceMobx(); return this.childDocList(this.fieldKey); } @computed get childLinks() { return this.childDocList("links"); } @computed get childAnnos() { return this.childDocList(this.fieldKey + "-annotations"); } @computed get boundsOfCollectionDocument() { @@ -130,13 +130,12 @@ export class TreeView extends React.Component<TreeViewProps> { constructor(props: any) { super(props); - console.log("Ttile = " + this.props.document.title); const titleScript = ScriptField.MakeScript(`{setInPlace(self, 'editTitle', '${this._uniqueId}'); documentView.select();} `, { documentView: "any" }); const openScript = ScriptField.MakeScript(`openOnRight(self)`); const treeOpenScript = ScriptField.MakeScript(`self.treeViewOpen = !self.treeViewOpen`); this._editTitleScript = !Doc.IsSystem(this.props.document) ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript); this._openScript = !Doc.IsSystem(this.props.document) ? openScript && (() => openScript) : undefined; - if (Doc.GetT(this.doc, "editTitle", "string", true) === "*") Doc.SetInPlace(this.doc, "editTitle", this._uniqueId, false); + if (Doc.GetT(this.props.document, "editTitle", "string", true) === "*") Doc.SetInPlace(this.props.document, "editTitle", this._uniqueId, false); } protected createTreeDropTarget = (ele: HTMLDivElement) => { @@ -185,7 +184,7 @@ export class TreeView extends React.Component<TreeViewProps> { } public static makeTextBullet() { - const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10 }); + const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", forceActive: true, _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10 }); Doc.GetProto(bullet).layout = CollectionView.LayoutString("data"); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); Doc.GetProto(bullet).data = new List<Doc>([]); @@ -659,8 +658,7 @@ export class TreeView extends React.Component<TreeViewProps> { onChildClick: undefined | (() => ScriptField), ignoreFields: string[] | undefined, firstLevel: boolean, - whenActiveChanged: (isActive: boolean) => void - ) { + whenActiveChanged: (isActive: boolean) => void) { const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField); if (viewSpecScript) { childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result); @@ -691,7 +689,7 @@ export class TreeView extends React.Component<TreeViewProps> { } const rowWidth = () => panelWidth() - 20; - return docs.map((child, i) => { + return docs.filter(child => child instanceof Doc).map((child, i) => { const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child); if (!pair.layout || pair.data instanceof Promise) { return (null); @@ -727,13 +725,12 @@ export class TreeView extends React.Component<TreeViewProps> { const aspect = NumCast(childLayout._nativeWidth, 0) / NumCast(childLayout._nativeHeight, 0); return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym](); }; - return !(child instanceof Doc) ? (null) : <TreeView + return <TreeView key={child[Id]} document={pair.layout} dataDoc={pair.data} containingCollection={containingCollection} prevSibling={docs[i]} treeView={treeView} - key={child[Id]} indentDocument={indent} outdentDocument={!parentCollectionDoc ? undefined : outdent} onCheckedClick={onCheckedClick} |
